2017-07-27 8 views
-2
1 
1one 
2 
2two 
11 
11eleven 
11 
22twentytwo 
111oneeleven 
552 
3311 
A1 
A10 
A11 
A100 
AB1 
AB10 
AB10A 
AB100 
AB100 
B1 
B2 
B3 
B3 
B20 
B20BB 
B21BC 
B21 
B32 

上記のソート順のリストが必要です。VARCHAR列を英数字のエントリでソートする(数値で始まる)

1 
2 
11 
11 
552 
3311 
1one 
2two 
11eleven 
22twentytwo 
111oneeleven 
A1 
A10 
A11 
A100 
AB1 
AB10 
AB10A 
AB100 
AB100 
B1 
B2 
B3 
B3 
B20 
B20BB 
B21BC 
B21 
B32 

クエリは次のとおりです。

ここ
SELECT 
    Section, 
    LEFT(Section, PATINDEX('%[0-9]%', Section) - 1) AS left1, 
    PATINDEX('%[0-9]%', Section) startindex, 
    LEN(Section) AS length, 
    PATINDEX('%[0-9]%', REVERSE(Section)) AS revindex, 
    LEN(Section) - PATINDEX('%[0-9]%', REVERSE(Section)) + 1 positionofendint, 
    SUBSTRING(Section, PATINDEX('%[0-9]%', Section), LEN(Section) - PATINDEX('%[0-9]%', REVERSE(Section)) + 1) integerpart, 
    LEN(Section) - PATINDEX('%[0-9]%', REVERSE(Section)) + 1 - PATINDEX('%[0-9]%', Section) + 1 subintlength, 
    ISNUMERIC(section) isnumeric1, 
    LEFT(Section, PATINDEX('[0-9]', Section)) onlyint 
FROM 
    dbo.Section 
WHERE 
    section NOT IN ('33A100', '55B32', '55B1', '55AB100', '99AB10A', '99B21BC', '1B20BB', '6B2B', '3AB1', '4a1', '7A11', '99B3') 
    --where section not like '%B%' and section not like '%A%' and section not like '%o%' and section not like '%e%' 
--ORDER BY section 
--, CONVERT(INT,(case when isnumeric(section)=1 then section end)) 
ORDER BY 
    LEFT(Section, PATINDEX('%[0-9]%', Section) - 1), -- alphabetical sort 
    CONVERT(INT, SUBSTRING(Section, PATINDEX('%[0-9]%', Section), 
    LEN(Section) - PATINDEX('%[0-9]%', REVERSE(Section)) + 1 - PATINDEX('%[0-9]%', Section) + 1)) -- numerical sort 

、Wordがアルファベットで開始番号もソートされているが、言葉は数字で開始がソートされていないことを、ソートや隣にいる、ソートする方法で私を助けてください単語は文字で数字を開始しました。

+0

あなたはMYSQLとSQL-SERVERの両方を持つことはできません、あなたは – Eli

+2

順序を使用していないRDMSのタグを削除してくださいあなたがあなたの並べ替えでデータ型を混合しているので、あなたが望むと言っているのは非常に困難です。すべての数値のみを最初にソートしたいのであって、文字データではなく数字のようにソートする必要がある場合、文字データを含む値で同じ方法でソートする必要があります。あなたは本当にこれをすることはできません。 –

+0

@SeanLange私は解決策を見つけたと信じていますが、私はひどく間違っていたところを教えてくれます。**編集:**自分で実現しました。私は近づいていますが、英数字のソートはAB10Aのような値にミックスアップされます。 – Santi

答えて

1

多分単純なケースの声明ですか?これは具体的にはあなたの結果と一致しませんが、varcharの部分を、(できるかもしれない)部分と整数部分の後ろに正しくソートします。

私はあなたが後にしている CASEは、このようなものであると信じてい
declare @table table (v varchar(64)) 
insert into @table 
values 
('1'), 
('1one'), 
('2'), 
('2two'), 
('11'), 
('11eleven'), 
('11'), 
('22twentytwo'), 
('111oneeleven'), 
('552'), 
('3311'), 
('A1'), 
('A10'), 
('A11'), 
('A100'), 
('AB1'), 
('AB10'), 
('AB10A'), 
('AB100'), 
('AB100'), 
('B1'), 
('B2'), 
('B3'), 
('B3'), 
('B20'), 
('B20BB'), 
('B21BC'), 
('B21'), 
('B32') 

select v 
from @table 
order by case when v like '%[^0-9]%' then v end, v 
+0

これはかなり良いですが、実際にはOPはこのデータを本当に難しい方法で並べ替えることを望んでいます。文字データが数字と文字でどのようにソートされているかに注目してください。 –

+0

私は@SeanLangeに同意しています。そして、あなたは長さをどのように最初に並べ替える必要があるように思えるでしょうか?奇妙なことに同意しますが、それが始まるでしょう。 – scsimon

+1

私はあなたが最初にそれらの値を上の数字だけで数値で並べ替える必要があると思います。その後、残りの部分は先行する数値を見つけ出し、先行する数値によって並べ替える必要があります。最後に、文字でソートされた最後のデータを追加します。どのような悪夢の混乱。 –

1

SELECT Section 
FROM dbo.Section 
ORDER BY 
    --Primary sort puts results that start with a letter to the end 
    --Otherwise, sorts by where the occurrence of the first letter is 
    CASE PATINDEX('%[^0-9]%', Section) WHEN 1 then 99 ELSE PATINDEX('%[^0-9]%', Section) END, 

    --Secondary sort will sort numeric values by length instead of number 
    CASE PATINDEX('%[^0-9]%', Section) WHEN 1 then 99 ELSE LEN(Section) END, 

    --Final sort alpha-numeric 
    Section 

answerはこれをテストするために必要なテーブルの作成を誰が行うスクリプトだ、scsimonをお願い致します。)

EDIT:上記のクエリはあなたに近いですが、英数字のソートには問題があります。 AB10A(など)の前にAB100を返します。より深く見ていきます。

+1

これは近いがまだそれほどではない。ソートの第2ラウンドは、文字データの先頭の数字でソートする必要があります。この作業を誤って表示するには '2to'を '2to'に変更してください。この種の並べ替えはひどいです。 –

+0

ええ、私はちょうど実現しました、ありがとう。今度は金田がこれで自分を燃やしましたが、後で元気に戻ってくる予定です。 – Santi

+0

ご返信ありがとうございます、それはほぼ終了しました。 – sreehari

0

このようにそれを試してみてください...

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData; 

SELECT 
    x.SomeValue 
    INTO #TestData 
FROM 
    (VALUES 
     ('1'), ('1one'), ('2'), ('2two'), ('11'), ('11eleven'), ('11'), ('22twentytwo'), ('111oneeleven'), 
     ('552'), ('3311'), ('A1'), ('A10'), ('A11'), ('A100'), ('AB1'), ('AB10'), ('AB10A'), ('AB100'), 
     ('AB100'), ('B1'), ('B2'), ('B3'), ('B3'), ('B20'), ('B20BB'), ('B21BC'), ('B21'), ('B32') 
    ) x (SomeValue); 

SELECT 
    td.SomeValue 
FROM 
    #TestData td 

ORDER BY 

    CASE WHEN td.SomeValue NOT LIKE '%[^0-9]%' THEN CAST(td.SomeValue AS INT) ELSE 2147483647 END, 
    CASE WHEN LEFT(td.SomeValue, 1) BETWEEN '0' AND '9' AND td.SomeValue LIKE '%[^0-9]%' THEN CAST(SUBSTRING(td.SomeValue, 1, PATINDEX('%[^0-9]%', td.SomeValue) - 1) AS INT) ELSE 2147483647 END,  
    td.SomeValue; 

HTH、ジェイソン

関連する問題