web-dev-qa-db-ja.com

PostgreSQLのORDER BYで大文字と小文字が区別されないのはなぜですか?

私はPostgres 9.4.4をDebianで実行していて、次のORDER BY動作を取得します。

veure_test=# show LC_COLLATE;
 lc_collate  
-------------
 en_US.UTF-8
(1 row)

veure_test=# SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') ORDER BY 1;
 regexp_split_to_table 
-----------------------
 a
 A
 b
 c
 Capacitor
 CD
 d
 D
(8 rows)

そしてuname -a

Linux ---- 3.2.0-4-AMD64 #1 SMP Debian 3.2.65-1 x86_64 GNU/Linux

しかし、Postgres 9.3.4を搭載したiMacでは、次のようになります。

veure_test=# show LC_COLLATE;
 lc_collate  
-------------
 en_US.UTF-8
(1 row)

veure_test=# SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') ORDER BY 1;
 regexp_split_to_table 
-----------------------
 A
 CD
 Capacitor
 D
 a
 b
 c
 d
(8 rows)

そしてuname -a

Darwin ---- 14.4.0 Darwin Kernel Version 14.4.0: Thu May 28 11:35:04 PDT 2015; root:xnu-2782.30.5~1/RELEASE_X86_64 x86_64

Debianのバージョンでは大文字と小文字が区別されないように見え、OS Xのバージョンではそうでない理由に私は不思議に思っています。何が欠けているか、または他にどのような情報を提供する必要がありますか?

更新:私のMacではpg_collationテーブルにen_US.UTF-8照合順序があることが示されていますが、Debianではen_US.utf8照合順序があります。したがって、私のMacでは:

veure_test=# with foo as (
SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') as bar
   )
SELECT bar FROM foo
ORDER BY bar collate "en_US.UTF-8";                                                                                                                                                                                      
    bar    
-----------
 A
 CD
 Capacitor
 D
 a
 b
 c
 d
(8 rows)

そしてDebianでは:

veure_test=# with foo as (
SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') as bar
   )
SELECT bar FROM foo
ORDER BY bar collate "en_US.utf8";
    bar    
-----------
 a
 A
 b
 c
 Capacitor
 CD
 d
 D
(8 rows)

では、en_US.UTF-8en_US.utf8のソート順は異なりますか?

29
Curtis Poe

では、_en_US.UTF-8_と_en_US.utf8_のソート順は異なりますか?

いいえ、どちらも同じですが、命名規則が異なります。

Debianのバージョンでは大文字と小文字が区別されないように見え、OS Xのバージョンではそうでない理由に私は不思議に思っています。

はい。それで合っています。これはMacのデフォルトの動作です。照合は、_UTF8_エンコーディングのBSD系OS(OSXを含む)では機能しません。

以下は、それを証明するためのリファレンスです。

ソート順の問題(UTF8ロケールは機能しません

a_horse_with_no_name が言ったように、PostgresはOSからの照合実装を使用します。両方のオペレーティングシステムで同じ結果を得る方法はありません。

あなたの場合、あなたは次のようにすることができます(多分言ったでしょう):ORDER BY lower(fieldname)

19
JSapkota