Postrgesは初めてで、varchar型の列を並べ替えたいと思っています。以下の例で問題を説明したい:
テーブル名:testsorting
order name
1 b
2 B
3 a
4 a1
5 a11
6 a2
7 a20
8 A
9 a19
大文字と小文字を区別する並べ替え(postgresではデフォルト)は次のようになります:
select name from testsorting order by name;
A
B
a
a1
a11
a19
a2
a20
b
大文字と小文字を区別しない並べ替えでは次のようになります:
uPPER(name);によるテストソート順から名前を選択します。
A
a
a1
a11
a19
a2
a20
B
b
postgresで英数字の大文字と小文字を区別しない並べ替えを行って順序を下回るにはどうすればよいですか:
a
A
a1
a2
a11
a19
a20
b
B
大文字または小文字の順序は気になりませんが、順序は「aAbB」または「AaBb」であり、「ABab」であってはなりません。
Postgresでこれに対する解決策があるかどうか提案してください。
私のPostgreSQLはあなたが望むようにソートします。 PostgreSQLが文字列を比較する方法は、ロケールと照合順序によって決まります。 createdb
を使用してデータベースを作成する場合、ロケールを設定するための-l
オプションがあります。また、psql -l
を使用して、環境でどのように構成されているかを確認できます。
[postgres@test]$ psql -l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------+----------+----------+------------+------------+-----------------------
mn_test | postgres | UTF8 | pl_PL.UTF8 | pl_PL.UTF8 |
ご覧のとおり、私のデータベースはポーランド語の照合を使用しています。
他の照合順序を使用してデータベースを作成した場合は、次のようにクエリで他の照合順序を使用できます。
SELECT * FROM sort_test ORDER BY name COLLATE "C";
SELECT * FROM sort_test ORDER BY name COLLATE "default";
SELECT * FROM sort_test ORDER BY name COLLATE "pl_PL";
次の方法で利用可能な照合順序を一覧表示できます。
SELECT * FROM pg_collation;
編集済み:
ああ、「a11」が「a2」の前にあるに違いないことを見逃しました。
標準の照合で英数字の並べ替えを解決できるとは思いません。このような並べ替えでは、Clodoaldo Netoの応答と同様に、文字列をパーツに分割する必要があります。この方法で頻繁に注文する必要がある場合に役立つもう1つのオプションは、名前フィールドを2つの列に分割することです。 INSERTとUPDATEで、name
をname_1
とname_2
に分割するトリガーを作成してから次のことを行うことができます。
SELECT name FROM sort_test ORDER BY name_1 COLLATE "en_EN", name_2;
(照合順序をポーランド語から英語に変更しました。ネイティブ照合順序を使用して、aącćなどの文字を並べ替える必要があります)
名前が常に1 alpha followed by n numerics
形式の場合、次のようになります。
select name
from testsorting
order by
upper(left(name, 1)),
(substring(name from 2) || '0')::integer
これ から強くインスピレーションを得た回答。
関数を使用すると、さまざまなクエリで必要になった場合に、関数をクリーンに保つことが簡単になります。
CREATE OR REPLACE FUNCTION alphanum(str anyelement)
RETURNS anyelement AS $$
BEGIN
RETURN (SUBSTRING(str, '^[^0-9]*'),
COALESCE(SUBSTRING(str, '[0-9]+')::INT, -1) + 2000000);
END;
$$ LANGUAGE plpgsql IMMUTABLE;
次に、次のように使用できます。
SELECT name FROM testsorting ORDER BY alphanum(name);
テスト:
WITH x(name) AS (VALUES ('b'), ('B'), ('a'), ('a1'),
('a11'), ('a2'), ('a20'), ('A'), ('a19'))
SELECT name, alphanum(name) FROM x ORDER BY alphanum(name);
name | alphanum
------+-------------
a | (a,1999999)
A | (A,1999999)
a1 | (a,2000001)
a2 | (a,2000002)
a11 | (a,2000011)
a19 | (a,2000019)
a20 | (a,2000020)
b | (b,1999999)
B | (B,1999999)
PostgreSQLは、Cライブラリロケール機能を使用して文字列を並べ替えます。 Cライブラリは、ホストオペレーティングシステムによって提供されます。 Mac OS XまたはBSDファミリのオペレーティングシステムでは、UTF-8ロケール定義が壊れているため、結果は照合順序「C」のとおりです。
ホストOSとしてubuntu 15.04を使用した照合結果用に添付された画像
詳細については、postgres wikiのFAQを確認してください: https://wiki.postgresql.org/wiki/FAQ
私に関する限り、私はPostgreSQLモジュールcitext
を使用し、CITEXT
の代わりにデータ型TEXT
を使用しました。これらの列での並べ替えと検索の両方で大文字と小文字が区別されなくなります。
モジュールはSQLコマンドCREATE EXTENSION IF NOT EXISTS citext;
でインストールできます