2

英数字トークンのリストがあり'1a', '1b', '02', '03', '10', '11',ます。

さて、このトークンのリストで注文するための最良の方法は何ですか?

私は得ています'1a', '1b', '10', '11', '02', '03',

しかし、私はそれが必要です

'1a', '1b', '02', '03', '10', '11' 

アップデート

わかりました、私は提案の後にこれをやっていますが、それは機能していません。

declare @tokens table(token varchar(20));

insert into @tokens
select '1a'
select '1b'
select '02'
select '10'

select * from @tokens
order by case
 when ISNUMERIC(token) = 1 then right('0000000000'+token+'0',10)
 else right('0000000000'+token,10)
 end

私は次のように応答を得ています'1b', '02', '10', '1a'

UPDATE2

以下の変更を行った後に動作します。

declare @tokens table(token varchar(20));

insert into @tokens
select '1a'
insert into @tokens
select '1b'
insert into @tokens
select '02'
insert into @tokens
select '10'


select token from @tokens
order by case
 when ISNUMERIC(token) = 1 then right('0000000000'+token+'0',10)
 else right('0000000000'+token,10)
 end

素敵なアイデアをありがとうございました。

4

3 に答える 3

9

最も簡単な解決策は、ゼロを事前に付加することです

Select ...
From Table
Order By Right( '0000000000' + YourColumn, 10)

ただし、これは英字を考慮しません。アルファ文字を処理するには、潜在的なアルファ文字の数を知る必要があります。ある場合は、次のようなことを行うことができます。

Select ...
From #Test
Order By Case
    When IsNumeric(NumVal) = 1 Then Right('0000000000' + NumVal + '0', 10)
    Else Right('0000000000' + NumVal, 10)
    End

添加

テスト走行:

If object_id('tempdb..#Test') is not null
    Drop Table #Test

Create Table #Test ( NumVal varchar(10) )
Insert #Test(NumVal) Values('02')
Insert #Test(NumVal) Values('03')
Insert #Test(NumVal) Values('1a')
Insert #Test(NumVal) Values('1b')
Insert #Test(NumVal) Values('10')
Insert #Test(NumVal) Values('11')

Select NumVal
From #Test
Order By Case
    When IsNumeric(NumVal) = 1 Then Right('0000000000' + NumVal + '0', 10)
    Else Right('0000000000' + NumVal, 10)
    End

Results:
1a
1b
02
03
10
11

私の解決策についてのメモ。アルファベット文字に特別な意味がある場合は、Erick Robertsonが提案したように、データを別々の列に分割する必要があります。上記のソリューションは、2つの非常に特殊なケースのみを処理します。すべて数値、末尾に1つのアルファベット文字が含まれる値です。データに複数の英字が含まれている可能性がある場合、または英字が値の末尾以外に配置されている場合、私のソリューションは機能しません。さらに、私のソリューションでは、テーブルスキャンによって各値の順序付け可能な文字列が評価されることに注意してください。

あなたが求めているのが1回限りの迅速な解決策であれば、私のアプローチはうまくいくでしょう。長期的な解決策を探している場合は、データを個別の列に分割するか、間抜けな並べ替え順序を受け入れるか、各値の相対的な並べ替え順序を指定する列を追加します。

于 2010-07-24T18:42:44.947 に答える
2

C#またはVB.netに精通している場合は、並べ替えを実行するCLR関数を作成することを検討する価値があります。この並べ替え順序は非標準であるため、TSQLで包括的かつ正確に説明するのは非常に困難です。

于 2010-07-24T18:57:21.757 に答える
1

最善の解決策は、トークンのint値を格納する別のフィールドを用意することです。トークン列を維持するときは、この列を維持する必要があります。次に、並べ替えるときに、int値列、トークン列の順に並べ替えます。これにより、これらの列にインデックスを付けて、大きなデータセットを持つデータをすばやく取得できるようになります。

alphaからintへの変換関数は低速であり、インデックス付けを利用してクエリを高速化することはできません。データセットが大きくなるにつれて、このタイプのソリューションは遅くなり、データベースを停止させるだけです。

于 2010-07-24T18:47:13.860 に答える