我有這張桌子:
IF OBJECT_ID('tempdb..#Test') IS NOT NULL
DROP TABLE #Test;
CREATE TABLE #Test (Col VARCHAR(100));
INSERT INTO #Test
VALUES ('1'), ('2'), ('10'), ('A'), ('B'), ('C1'), ('1D'), ('10HH')
SELECT * FROM #Test
我想先按數值排序,然后按字母順序排序。
我想要的結果是:
1
1D
2
10
10HH
A
B
C1
假設條目的結構是其中之一(當然沒有破折號)
number
number-string
string-number
string
如果有像 string-number-string 這樣的條目,假設它是 string-number
uj5u.com熱心網友回復:
它不漂亮,但它有效。
SELECT T.Col
FROM #Test T
CROSS APPLY (VALUES(PATINDEX('%[^0-9]%',T.Col)))PI(I)
CROSS APPLY (VALUES(TRY_CONVERT(int,NULLIF(ISNULL(LEFT(T.Col,NULLIF(PI.I,0)-1),LEN(T.Col)),''))))TC(L)
ORDER BY CASE WHEN TC.L IS NULL THEN 1 ELSE 0 END,
TC.L,
T.Col;
老實說,我建議如果您想像數值一樣排序資料,您實際上將數值存盤在數值列中;顯然上面應該是一個數字前綴值,然后是字串后綴。如果您隨后想要擁有您擁有的值,請使用 ( PERSISTED) 計算列。像這樣:
CREATE TABLE #Test (Prefix int NULL,
Suffix varchar(100) NULL,
Col AS CONCAT(Prefix, Suffix) PERSISTED);
INSERT INTO #Test (Prefix, Suffix)
VALUES (1,NULL), (2,NULL), (10,NULL), (NULL,'A'), (NULL,'B'), (NULL,'C1'), (1,'D'), (10,'HH');
SELECT Col
FROM #Test
ORDER BY CASE WHEN Prefix IS NULL THEN 1 ELSE 0 END,
Prefix,
Suffix;
uj5u.com熱心網友回復:
這種糟糕且不直觀的解決方案,如果您分別存盤由壞主意設計? 帶給您的兩段資料,則沒有必要:
;WITH cte AS
(
SELECT Col, rest = SUBSTRING(Col, pos, 100),
possible_int = TRY_CONVERT(bigint, CASE WHEN pos <> 1 THEN
LEFT(Col, COALESCE(NULLIF(pos,0),100)-1) END)
FROM (SELECT Col, pos = PATINDEX('%[^0-9]%', Col) FROM #Test) AS src
)
SELECT Col FROM cte
ORDER BY CASE
WHEN possible_int IS NULL THEN 2 ELSE 1 END,
possible_int,
rest;
結果:
| 上校 |
|---|
| 1 |
| 一維 |
| 2 |
| 10 |
| 10小時 |
| 一種 |
| 乙 |
| C1 |
- 示例資料庫<>小提琴
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/332834.html
標籤:sql sql-server 查询语句
上一篇:基于日期的動態資料透視表
