次の文字列を次の順序で並べ替える照合順序はありますか?1,2,3,6,10,10A、10B、11?


12

可変長の整数を含むVARCHAR列を持つデータベースがあります。私はそれらをソートして、10が1ではなく9の後に来るようにし、70Aが70の後に来るようにします。WHERE句のPATINDEX()、CTE、およびCASEステートメントでこれを行うことができました。

しかし、これが不必要な照合があるかどうか疑問に思っていました。


:ここでは今、Microsoftは接続からユーザーボイスに移行し、まだ前方にURIをなかったことがその提案のための新しいリンクで照合順序オプションとしてサポート「自然ソート」/ DIGITSASNUMBERS
ソロモンRutzky

2
Microsoftは、十分な票を得れば、これをSQL Serverの組み込み機能として実装すると述べています。だからここに行き、投票ボタンをクリックしてください
ピーターアイレット

回答:


8

いいえ。照合は、コードページ、アクセント、大文字と小文字、幅、かなに応じて、アルファベット順の並べ替えに関するものです。数字(0-9)にはプロパティがありません。

そのため9、常に後を追っ10Bます。

指摘したとおりに分割するか、次のようにソートする必要があります

ORDER BY
    RIGHT('                              ' + MyColumn, 30)

右側の長さによって、スペースの数が決まります。

もちろんできます:

  • これを不要に(そしてはるかに高速に)する2つの列があり、それらを結合する計算列があります
  • 先行ゼロを主張する
  • 文字(上記の右の保存バージョン)で右揃え

後者の2つの提案は、上記の私の右のようなもので、わずかに異なります。ソートは高速(colukmnの処理は不要)、より多くのストレージが必要


これがどのように機能するかわかりません。
2、2a

@Mladen Prajdic:あなたは正しい、おっと。末尾のアルファベットを忘れた
-gbn

So 9は常に10Bあらゆる並べ替えの後です」に関して:SQL Serverでは、「DigitsAsNumbers」を処理するための基になる並べ替えオプションが照合オプションとして公開されていないため、その方法に過ぎません。まだ;-)。これは、Windows 7以降、特にFile ExplorerでWindowsベースのアプリで利用できるようになりました。そして、十分な人がこのアイデアをサポートしていれば、いつかSQL Serverにさらされる可能性があります。次のConnectの提案を提出して、ボールを転がそうとしました:照合オプションとして「自然な並べ替え」/ DIGITSASNUMBERSをサポートします
ソロモンラッツキー16

8

計算列を設定し、それに基づいて並べ替えます。何かのようなもの

CAST( 
     CASE WHEN IS_NUMERIC(left(OtherColumn, 2) = 1) then 
         left(OtherColumn,2) 
     else 
         left(otherColumn, 1)  
AS INT)

次に、この列を使用して、列のインデックスを作成できるように並べ替えます。


同様の問題について知っておくと本当に便利です。ただし、この場合、スキーマを変更することはできません。
ジャスティンディアリング

スキーマに追加できますか?計算列がなければ、いつでもビューを作成できます。ただし、実際には計算列のように最適化することはできません。
アーロンバートランド

インデックス付きビューを実行し、Enterpriseエディションを使用している場合、何をしようとしているかがわかる場合、クエリはインデックス付きビューを自動的に使用します。標準エディションの場合、WITH(NOEXPAND)を使用して、インデックス付きビューを使用する必要があります。その時点で、注文文にcase文を含める必要がありますが、うまくいくはずです。
mrdenny

計算列を作成する必要はありません。この式は、ORDER BY句で直接使用できます
-a_horse_with_no_name

インデックスまたはテーブルスキャンを保証する場合は、可能です。値にインデックスを付けたい場合は、計算列またはインデックス付きビューが必要です。
-mrdenny

5

@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を試行していない)は期待どおりに並べ替えられます。ソートを定義するには別の方法が必要です。


2

文字列内の数字を実際の数字としてソートする賢明で効率的な手段が必要ですか?Microsoft Connectの提案に投票することを検討してください。照合オプションとして「自然な並べ替え」/ DIGITSASNUMBERSをサポートしてください


この質問は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 Collat​​ion 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エクスプローラでファイルのリストを見ると、「数値」オプションを使用してソートされたリストが表示されます:-)。


参考までに、Postgres 10はICU照合のサポートを獲得しました。Peter Eisentrautによるこのブログ投稿を参照してください。
バジルブルク

@BasilBourque PG10について言及してくれてありがとう。最後のブログ投稿では、「ICUはこの分野で、PostgreSQLを通じてまだ公開されていない多くの機能を提供しています。大文字と小文字を区別しないソート、アクセントを区別しないソート、照合の完全カスタマイズのオプションがあります。見てください。将来のPostgreSQLリリースのユーザー向け。」したがって、その最初/現在の実装では、私の答えの情報は変更されません。将来のオファリングで数値の並べ替えが可能になった場合、回答でそれを言及しますが、この質問はSQL Server固有であるため、脚注として言及します。
ソロモンラッツキー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.