可変長の整数を含むVARCHAR列を持つデータベースがあります。私はそれらをソートして、10が1ではなく9の後に来るようにし、70Aが70の後に来るようにします。WHERE句のPATINDEX()、CTE、およびCASEステートメントでこれを行うことができました。
しかし、これが不必要な照合があるかどうか疑問に思っていました。
可変長の整数を含むVARCHAR列を持つデータベースがあります。私はそれらをソートして、10が1ではなく9の後に来るようにし、70Aが70の後に来るようにします。WHERE句のPATINDEX()、CTE、およびCASEステートメントでこれを行うことができました。
しかし、これが不必要な照合があるかどうか疑問に思っていました。
回答:
いいえ。照合は、コードページ、アクセント、大文字と小文字、幅、かなに応じて、アルファベット順の並べ替えに関するものです。数字(0-9)にはプロパティがありません。
そのため9
、常に後を追っ10B
ています。
指摘したとおりに分割するか、次のようにソートする必要があります。
ORDER BY
RIGHT(' ' + MyColumn, 30)
右側の長さによって、スペースの数が決まります。
もちろんできます:
後者の2つの提案は、上記の私の右のようなもので、わずかに異なります。ソートは高速(colukmnの処理は不要)、より多くのストレージが必要
9
は常に10B
あらゆる並べ替えの後です」に関して:SQL Serverでは、「DigitsAsNumbers」を処理するための基になる並べ替えオプションが照合オプションとして公開されていないため、その方法に過ぎません。まだ;-)。これは、Windows 7以降、特にFile ExplorerでWindowsベースのアプリで利用できるようになりました。そして、十分な人がこのアイデアをサポートしていれば、いつかSQL Serverにさらされる可能性があります。次のConnectの提案を提出して、ボールを転がそうとしました:照合オプションとして「自然な並べ替え」/ DIGITSASNUMBERSをサポートします。
計算列を設定し、それに基づいて並べ替えます。何かのようなもの
CAST(
CASE WHEN IS_NUMERIC(left(OtherColumn, 2) = 1) then
left(OtherColumn,2)
else
left(otherColumn, 1)
AS INT)
次に、この列を使用して、列のインデックスを作成できるように並べ替えます。
@gbnが言っていることを証明するための苦痛な方法が必要な場合(基本的に、照合にサブストリングの順序を変えることはできません)、期待する順序の係数を持つ簡単な#tempテーブルを作成し、照合による順序付けは、同じ順序を返します。
CREATE TABLE #foo(id INT, n NVARCHAR(10));
CREATE TABLE #bar(collation SYSNAME);
SET NOCOUNT ON;
INSERT #foo SELECT 1,'1'
UNION SELECT 2,'2'
UNION SELECT 3,'3'
UNION SELECT 4,'6'
UNION SELECT 5,'10'
UNION SELECT 6,'10A'
UNION SELECT 7,'10B'
UNION SELECT 8,'11';
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'
WITH x AS
(
SELECT n, rn = ROW_NUMBER() OVER
(ORDER BY n COLLATE ' + name + ') FROM #foo
)
INSERT #bar
SELECT TOP (1) ''' + name + ''' FROM x
WHERE NOT EXISTS
(
SELECT COUNT(*) FROM #foo AS f
WHERE f.id = x.rn
AND f.n <> x.n
);' FROM sys.fn_helpcollations();
EXEC sp_executesql @sql;
SELECT collation FROM #bar;
GO
DROP TABLE #foo, #bar;
これは約10秒で実行され、0行が生成されます。つまり、SQL Serverで使用可能な照合(少なくとも2008 R2、Denaliを試行していない)は期待どおりに並べ替えられます。ソートを定義するには別の方法が必要です。
この質問はSQL Serverに固有のものであり、この回答はそうではありませんが、他の回答に反対しないように、単に認識を高めるためにこの情報を投稿する必要があると感じました。
つまり、SQL Serverの外部では、特定の環境ではこの種類の並べ替えが可能です。少なくともUnicodeのドキュメントで指定されているものです。でUNICODEロケール・データ・マークアップ言語(LDML)PART 5:COLLATIONの標準/レポートのためのチャートがある照合順序の設定、ソート動作を調整するためのさまざまなオプションを説明しています。オプションの1つは、-kn-true
または[numericOrdering on]
:
onに設定されている場合、10進数のシーケンス([ UAX44 ]のGeneral_Category = Nd )は、数値とともにプライマリレベルでソートされます。たとえば、「A-21」<「A-123」です。計算されたプライマリウェイトはすべて、数字の並べ替えグループの先頭にあります。したがって、未調整のUCAテーブルでは、「a $」<「a0」<「a2」<「a12」<「a⓪」<「aa」です。
ただし、このドキュメントは「技術標準」であり、コアUnicode仕様の一部ではありません。ドキュメントの上部にあるメモには、次のように記載されています。
Unicode Technical Standard(UTS)は独立した仕様です。Unicode標準への準拠は、UTSへの準拠を意味するものではありません。
したがって、両方ともコアUnicode仕様に準拠していても、この特定の動作はSQL Serverまたは.NET(少なくともネイティブではない)で使用できません。
ICUのプロジェクト(Unicodeの国際コンポーネント)は、この機能を実装することをC / C ++とJavaライブラリのセットであり、それでさえオンラインデモがあります。「関連プロジェクト」の下には、ICUライブラリのCOMオブジェクトラッパーと思われる.NETプロジェクトへのリンクがあり、この機能をマネージコードに公開できます。しかし、その.NETプロジェクトがまだアクティブかどうかは明らかではありません。
しかし、この動作を実際に確認するには、ICU Collation Demoにアクセスしてください。
以下を左側の入力テキスト領域に貼り付けます。
1
2
10B
6
11
10A
3
10
すべてのオプションを「デフォルト」に設定します。sortボタンの右側にある「入力行番号」オプションをチェックし、「差分強度」オプションがオフになっていることを確認します。
sortボタンをクリックすると、次の結果が得られます。
[1] 1
[8] 10
[6] 10A
[3] 10B
[5] 11
[2] 2
[7] 3
[4] 6
これは、一般的な文字列の並べ替えを行うときに予想されることであり、SQL Serverで表示されるものです。
現在、ボタンのすぐ上の一連のラジオボタンsortでは、2行目に「数値」というラベルが付いています。「オン」ラジオボタンを選択します。
クリックsortボタンを再度、あなたは次のことを取り戻す必要があります。
[1] 1
[2] 2
[7] 3
[4] 6
[8] 10
[6] 10A
[3] 10B
[5] 11
数値部分が文字列の中央にあるときにこれが機能するかどうかを質問しますか?OK、左側の入力テキスト領域に以下を貼り付けます(前のリストを置き換えます):
Script - 1.sql
Script - 2.sql
Script - 10B.sql
Script - 6.sql
Script - 11.sql
Script - 10A.sql
Script - 3.sql
Script - 10.sql
数値設定がまだ「オン」に設定されていることを確認してください。クリックsortボタンを再度、あなたは次のことを取り戻す必要があります。
[1] Script - 1.sql
[2] Script - 2.sql
[7] Script - 3.sql
[4] Script - 6.sql
[8] Script - 10.sql
[6] Script - 10A.sql
[3] Script - 10B.sql
[5] Script - 11.sql
これを別の場所で見たいですか?ハードドライブにC:\ temp \ sorting \などのフォルダーを作成し、同じ「スクリプト-...」名の空のファイルを作成します。実行しDIR
、コマンドウィンドウで、あなたは標準のソートが表示されます。ただし、Windowsエクスプローラでファイルのリストを見ると、「数値」オプションを使用してソートされたリストが表示されます:-)。