SQL Server 2000
データベースにVARCHAR
列があり、文字または数字を含めることができます。これは、顧客のフロントエンドでアプリケーションがどのように構成されているかによって異なります。
数値が含まれている場合は、数値でソートする必要があります。 「1」、「10」、「2」の代わりに「1」、「2」、「10」として。文字のみ、または文字と数字(「A1」など)を含むフィールドは、通常どおりアルファベット順にソートできます。たとえば、これは許容可能なソート順です。
1
2
10
A
B
B1
これを達成する最良の方法は何ですか?
考えられる解決策の1つは、すべての文字列の長さが同じになるように、数値の前に文字を埋め込むことです。
そのアプローチを使用した例を次に示します。
select MyColumn
from MyTable
order by
case IsNumeric(MyColumn)
when 1 then Replicate('0', 100 - Len(MyColumn)) + MyColumn
else MyColumn
end
100
は、その列の実際の長さに置き換える必要があります。
これを行うには、いくつかの可能な方法があります。
一つは
SELECT
...
ORDER BY
CASE
WHEN ISNUMERIC(value) = 1 THEN CONVERT(INT, value)
ELSE 9999999 -- or something huge
END,
value
oRDER BYの最初の部分はすべてをintに変換し(最後に並べ替えるために非数値の巨大な値を使用)、最後の部分はアルファベットを処理します。
このクエリのパフォーマンスは、おそらく大量のデータに対して少なくとも中程度に恐ろしいことに注意してください。
SELECT *, CONVERT(int, your_column) AS your_column_int
FROM your_table
ORDER BY your_column_int
[〜#〜] or [〜#〜]
SELECT *, CAST(your_column AS int) AS your_column_int
FROM your_table
ORDER BY your_column_int
どちらもかなり移植性があると思います。
select
Field1, Field2...
from
Table1
order by
isnumeric(Field1) desc,
case when isnumeric(Field1) = 1 then cast(Field1 as int) else null end,
Field1
これにより、質問で指定した順序で値が返されます。
キャストがすべて実行されてもパフォーマンスはそれほど高くないため、別のアプローチは、データの整数コピーを格納するテーブルに別の列を追加し、最初にその列で、次に問題の列で並べ替えることです。これには、テーブルにデータを挿入または更新するロジックを変更して、両方の列にデータを取り込む必要があることは明らかです。それとも、データが挿入または更新されるたびに2番目の列にデータを挿入するためにテーブルにトリガーを配置します。
整数が短すぎる可能性があるため、varchar-columnをいつでもbigintに変換できます...
select cast([yourvarchar] as BIGINT)
しかし、常にアルファ文字に注意する必要があります
where ISNUMERIC([yourvarchar] +'e0') = 1
+ 'e0'は http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/isnumeric-isint-isnumber に由来します
これはあなたの声明につながります
SELECT
*
FROM
Table
ORDER BY
ISNUMERIC([yourvarchar] +'e0') DESC
, LEN([yourvarchar]) ASC
最初のソート列は数値を先頭に配置します。 2番目は長さでソートされるため、10が0001に先行します(これはバカですか?!)
これは、2番目のバージョンにつながります。
SELECT
*
FROM
Table
ORDER BY
ISNUMERIC([yourvarchar] +'e0') DESC
, RIGHT('00000000000000000000'+[yourvarchar], 20) ASC
2番目の列は右に「0」が埋め込まれるため、自然な並べ替えでは、先頭にゼロ(0、01、10、0100 ...)の整数が正しい順序で配置されます(正しい!)-ただし、すべてのアルファは「0」で拡張されます-chars(パフォーマンス)
3番目のバージョン:
SELECT
*
FROM
Table
ORDER BY
ISNUMERIC([yourvarchar] +'e0') DESC
, CASE WHEN ISNUMERIC([yourvarchar] +'e0') = 1
THEN RIGHT('00000000000000000000' + [yourvarchar], 20) ASC
ELSE LTRIM(RTRIM([yourvarchar]))
END ASC
現在、数字は最初に「0」文字で埋められます(もちろん、長さ20を拡張できます)-数字を正しく並べ替えます-アルファのみがトリミングされます
「順序」の部分にこれを書くことは非常に簡単な方法で解決しました
ORDER BY (
sr.codice +0
)
ASC
これは非常にうまくいくようで、実際、次のソートがありました。
16079 Customer X
016082 Customer Y
16413 Customer Z
0
の前に 16082
は正しく考慮されます。
これはうまくいくようです:
select your_column
from your_table
order by
case when isnumeric(your_column) = 1 then your_column else 999999999 end,
your_column
このクエリは役に立ちます。このクエリでは、varcharが適切な順序で並べられたデータ型の列があります。たとえば、この列のデータは次のとおりです。-G1、G34、G10、G3。したがって、このクエリを実行すると、結果が表示されます:-G1、G10、G3、G34。
SELECT *,
(CASE WHEN ISNUMERIC(column_name) = 1 THEN 0 ELSE 1 END) IsNum
FROM table_name
ORDER BY IsNum, LEN(column_name), column_name;
これはあなたを助けるかもしれません、私は同じ問題を抱えたときにこれを試しました。
SELECT * FROM tab ORDER BY IIF(TRY_CAST(val AS INT) IS NULL, 1, 0),TRY_CAST(val AS INT);
SELECT FIELD FROM TABLE
ORDER BY
isnumeric(FIELD) desc,
CASE ISNUMERIC(test)
WHEN 1 THEN CAST(CAST(test AS MONEY) AS INT)
ELSE NULL
END,
FIELD
このリンク に従って、「$」が数字として順序付けられないようにするには、MONEY、INTにキャストする必要があります。