多くのプログラミング言語では、>、> =、<などの演算子を使用して文字列を比較できます。言語は、アルファベットの文字の位置に基づいて比較を行います。
例えばPHPで
if ('a' < 'b') {
echo 'Yes';
} else {
echo 'No';
}
> Yes
ただし、postgresまたはmysqlでは
SELECT
CASE WHEN 'a' < 'b' THEN 'yes' END
FROM table
Output: null
SQLで相互に比較する必要がある文字列を含むテーブルがあります。
例:6.2(5a)6.2(5b)-これは6.2(5a)より大きくなるか、または6.2(15)-これは6.2(5a)より大きくなる
正規表現を使用して文字に数字を割り当てることを考えましたが、その場合、文字がないと比較ができなくなります。
純粋にSQLでこれにどう対処しますか?
[〜#〜]ノート[〜#〜]:赤いニシンで元の答えが出ました。
単純な比較では、文字ごとに並べ替えられます。
select 'a1' < 'a9'; -- true because 'a' = 'a' and '1' < '9'.
...しかしすぐにポットに行きます。
select 'a10' < 'a9'; -- also true for the same reason.
必要なのは 自然ソート で、文字列の部分は文字列として比較され、数値は数値として比較されます。 SQLで自然なソートを行うことは、最も簡単なことではありません。各部分文字列を個別に並べ替えるには、固定フィールド幅が必要か、正規表現を使用した何かが必要です...
幸いなことに pg_natural_sort_order があります。これは、効率的な自然ソートを実装するPostgres拡張機能です。
拡張機能をインストールできない場合は、2kanによって btrsort のようなストアドプロシージャを使用できます。
CREATE FUNCTION btrsort_nextunit(text) RETURNS text AS $$
SELECT
CASE WHEN $1 ~ '^[^0-9]+' THEN
COALESCE( SUBSTR( $1, LENGTH(SUBSTRING($1 FROM '[^0-9]+'))+1 ), '' )
ELSE
COALESCE( SUBSTR( $1, LENGTH(SUBSTRING($1 FROM '[0-9]+'))+1 ), '' )
END
$$ LANGUAGE SQL;
CREATE FUNCTION btrsort(text) RETURNS text AS $$
SELECT
CASE WHEN char_length($1)>0 THEN
CASE WHEN $1 ~ '^[^0-9]+' THEN
RPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[^0-9]+'), ''), 1, 12), 12, ' ') || btrsort(btrsort_nextunit($1))
ELSE
LPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[0-9]+'), ''), 1, 12), 12, ' ') || btrsort(btrsort_nextunit($1))
END
ELSE
$1
END
;
$$ LANGUAGE SQL;
それは比較演算子を提供していませんが、私はそれを理解するふりをするつもりはありません。これにより、order by
。
select * from things order by btrsort(whatever);
自然にソートされたクエリが大きなテーブルで泥に変わるのを防ぐために、 その関数の結果にbtreeインデックスを作成できます 。
create index things_whatever_btrsort_idx ON things( btrsort(whatever) );
SELECT CASE WHEN 'a' < 'b' THEN 'yes' END FROM table Output: null
これは、テーブルが空の場合のみ何も出力しません。 selectステートメントをテストするためにテーブルは必要ありません。
SELECT
CASE WHEN 'a' < 'b' THEN 'yes' END -- yes