通過其數字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
如何按升序排列顯示這個?
通過其數字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
如何按升序排列顯示這個?
你發生有一個四部分命名,所以你可以使用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
這並不完美,因爲您似乎有奇怪的放置圓括號。但它可能足以滿足你的目的。
也許我錯過了一些東西,但[這會產生語法錯誤](http://sqlfiddle.com/#!6/9c96b/1) – paqogomez
不錯!我喜歡使用'Parsename()',儘管我認爲它值得鏈接到MSDN。我編輯了你的答案來包含它,希望你不介意。 –
試試這個:
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)
試試這個
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
這應該工作:
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
我認爲你的輸出應該是不同的'1.1.1.QuestionText'會出現在'1.1.1(a).Questions';)之後。 –
可能會在其他機器上有所不同。我只是通過版本號訂購,而不是通過後面的文本訂購。 –
如果我理解你,你是試圖對數據的文本部分進行排序?而忽略數字?這些價值觀是否都在一個領域? – paqogomez
@paqogomez - 我必須排序所有的值(數字和文本),像第一個數字排序後跟字符。 –