2015-05-24 66 views
2

通過其數字varchar數據類型列我在SQL Server中包含這樣的數據的列:如何排序在SQL Server

1.1.1.QuestionText 
1.1.1.Question 
1.1.1(a).Questions 
1.1.2.Questionswithtext 
1.1.2(b).Text 
10.1.1.Answers 
2.1.1.Questions 
2.2.2.QuestionText 

如何按升序排列顯示這個?

+0

如果我理解你,你是試圖對數據的文本部分進行排序?而忽略數字?這些價值觀是否都在一個領域? – paqogomez

+0

@paqogomez - 我必須排序所有的值(數字和文本),像第一個數字排序後跟字符。 –

回答

1

發生有一個四部分命名,所以你可以使用parsename()。結果如下:

order by (case when isnumeric(arsename(col, 4)) = 1 then cast(parsename(col, 4) as int) 
      end), 
     (case when isnumeric(parsename(col, 3)) = 1 then cast(parsename(col, 3) as int) 
      end), 
     (case when isnumeric(parsename(col, 2)) = 1 then cast(parsename(col, 2) as int) 
      end), 
     (case when isnumeric(parsename(col, 1)) = 1 then cast(parsename(col, 1) as int) 
      end), 
     col 

這並不完美,因爲您似乎有奇怪的放置圓括號。但它可能足以滿足你的目的。

+1

也許我錯過了一些東西,但[這會產生語法錯誤](http://sqlfiddle.com/#!6/9c96b/1) – paqogomez

+1

不錯!我喜歡使用'Parsename()',儘管我認爲它值得鏈接到MSDN。我編輯了你的答案來包含它,希望你不介意。 –

0

試試這個:

 CREATE TABLE #TMP 
     (
     name nvarchar(30) 
     ) 

     INSERT INTO #TMP (name) VALUES ('1.1.1.QuestionText') 
     INSERT INTO #TMP (name) VALUES ('1.1.1.Question') 
     INSERT INTO #TMP (name) VALUES ('1.1.1(a).Questions') 
     INSERT INTO #TMP (name) VALUES ('1.1.2.Questionswithtext') 
     INSERT INTO #TMP (name) VALUES ('1.1.2(b).Text') 
     INSERT INTO #TMP (name) VALUES ('10.1.1.Answers') 
     INSERT INTO #TMP (name) VALUES ('2.1.1.Questions') 
     INSERT INTO #TMP (name) VALUES ('2.2.2.QuestionText') 

     select 
     SUBSTRING(replace(name, '.',''),1, 
       PATINDEX('%[^0-9]%', 
        replace(name, '.','') 
       ) -1 
      ) as replaced, name from #TMP order by 
     CAST( 
      SUBSTRING(replace(name, '.',''),1, 
       PATINDEX('%[^0-9]%', 
        replace(name, '.','') 
       ) -1 
      ) 
     as int) 

它的工作原理總是當它從數字開始。它僅由此第一個數字排序。如果您想通過數字第一和文本的其餘命令後,你可以(在順序我把在選擇同樣喜歡展現訂購零件)更改爲上次查詢:

 select 
     SUBSTRING(replace(name, '.',''),1, 
       PATINDEX('%[^0-9]%', 
        replace(name, '.','') 
       ) -1 
      ) as replacedDigit, 
      SUBSTRING(replace(name, '.',''), 
       PATINDEX('%[^0-9]%', 
        replace(name, '.','') 
       ), 100) as replacedText, 

      name from #TMP order by 
     CAST( 
      SUBSTRING(replace(name, '.',''),1, 
       PATINDEX('%[^0-9]%', 
        replace(name, '.','') 
       ) -1 
      ) 
     as int), SUBSTRING(replace(name, '.',''), 
       PATINDEX('%[^0-9]%', 
        replace(name, '.','') 
       ), 100) 
0

試試這個

SELECT * 
FROM t 
ORDER BY 
     CASE PATINDEX('%[^0-9]%', PARSENAME(name, 4)) 
      WHEN 0 THEN RIGHT('0000' + PARSENAME(name, 4), 4) 
      WHEN 1 THEN PARSENAME(name, 1) 
      ELSE RIGHT('0000' + SUBSTRING(PARSENAME(name, 2), 1, PATINDEX('%[^0-9]%', PARSENAME(name, 2)) - 1), 4) + SUBSTRING(PARSENAME(name, 2), PATINDEX('%[^0-9]%', PARSENAME(name, 2)), LEN(name)) 
     END 
    , CASE PATINDEX('%[^0-9]%', PARSENAME(name, 3)) 
      WHEN 0 THEN RIGHT('0000' + PARSENAME(name, 3), 4) 
      WHEN 1 THEN PARSENAME(name, 1) 
      ELSE RIGHT('0000' + SUBSTRING(PARSENAME(name, 2), 1, PATINDEX('%[^0-9]%', PARSENAME(name, 2)) - 1), 4) + SUBSTRING(PARSENAME(name, 2), PATINDEX('%[^0-9]%', PARSENAME(name, 2)), LEN(name)) 
     END 
    , CASE PATINDEX('%[^0-9]%', PARSENAME(name, 2)) 
      WHEN 0 THEN RIGHT('0000' + PARSENAME(name, 2), 4) 
      WHEN 1 THEN PARSENAME(name, 1) 
      ELSE RIGHT('0000' + SUBSTRING(PARSENAME(name, 2), 1, PATINDEX('%[^0-9]%', PARSENAME(name, 2)) - 1), 4) + SUBSTRING(PARSENAME(name, 2), PATINDEX('%[^0-9]%', PARSENAME(name, 2)), LEN(name)) 
     END 
    , CASE PATINDEX('%[^0-9]%', PARSENAME(name, 1)) 
      WHEN 0 THEN RIGHT('0000' + PARSENAME(name, 1), 4) 
      WHEN 1 THEN PARSENAME(name, 1) 
      ELSE RIGHT('0000' + SUBSTRING(PARSENAME(name, 2), 1, PATINDEX('%[^0-9]%', PARSENAME(name, 2)) - 1), 4) + SUBSTRING(PARSENAME(name, 2), PATINDEX('%[^0-9]%', PARSENAME(name, 2)), LEN(name)) 
     END 

對於這一點:

1.1.1.Question 
1.1.1.QuestionText 
1.1.1(a).Questions 
1.1.2.Questionswithtext 
1.1.2(b).Text 
2.1.1.Questions 
2.2.2.QuestionText 
10.1.1.Answers 
1

這應該工作:

SELECT name 
FROM (SELECT name, SUBSTRING(name, 1, 
           LEN(name) - PATINDEX('%[0-9]%', REVERSE(name)) + 1) n 
      FROM  #tmp 
     ) v 
ORDER BY CAST(PARSENAME(n, 4) AS INT), 
     CAST(PARSENAME(n, 3) AS INT), 
     CAST(PARSENAME(n, 2) AS INT), 
     CAST(PARSENAME(n, 1) AS INT) 

輸出:

name 
1.1.1.QuestionText 
1.1.1.Question 
1.1.1(a).Questions 
1.1.2.Questionswithtext 
1.1.2(b).Text 
2.1.1.Questions 
2.2.2.QuestionText 
10.1.1.Answers 

如果要通過後版本號的文本命令,那麼這將工作:

SELECT name 
FROM (SELECT name, SUBSTRING(name, 1, 
           LEN(name) - PATINDEX('%[0-9]%', REVERSE(name)) + 1) nv, 
          SUBSTRING(name, LEN(name) - PATINDEX('%[0-9]%', REVERSE(name)) + 2, 
           LEN(name)) nt        
      FROM  #tmp 
     ) v 
ORDER BY CAST(PARSENAME(nv, 4) AS INT), 
     CAST(PARSENAME(nv, 3) AS INT), 
     CAST(PARSENAME(nv, 2) AS INT), 
     CAST(PARSENAME(nv, 1) AS INT), 
     nt 

輸出:

name 
1.1.1(a).Questions 
1.1.1.Question 
1.1.1.QuestionText 
1.1.2(b).Text 
1.1.2.Questionswithtext 
2.1.1.Questions 
2.2.2.QuestionText 
10.1.1.Answers 
+0

我認爲你的輸出應該是不同的'1.1.1.QuestionText'會出現在'1.1.1(a).Questions';)之後。 –

+1

可能會在其他機器上有所不同。我只是通過版本號訂購,而不是通過後面的文本訂購。 –