2017-04-04 42 views
0
SELECT varcharColumn 
FROM tableA 
ORDER BY varcharColumn ASC 

给我排序包含数字与破折号VARCHAR列(1060006-19)

1060006-1 
1060006-10 
1060006-11 
1060006-12 
1060006-13 
1060006-15 
1060006-16 
1060006-17 
1060006-18 
1060006-19 
1060006-20 
1060006-2 

我要的是

1060006-1 
1060006-2 
1060006-3 

可以通过实现这个?或者我需要更多的东西?

使用这个给我在下面的图片结果:

ORDER BY 
CASE WHEN varcharcolumn like '%-%' THEN 1 ELSE 2 END, 
LEN(varcharcolumn) 

enter image description here

+0

您所感兴趣的两个独立的字符串(你要正确对待字符串“1060006-2”,就好像它在两个号码1060006和2个或两个字符串“1060006 '和'02')表示这应该是两个单独的列。您可能希望在表格设计中更改此类查询,并且像这里所需的查询将变得非常简单。 –

+0

我同意,因为破折号后面的数字是一个版本号。但是太多的东西依赖于目前的设置,我不认为我有时间去改变它。 –

+0

一般情况。不幸的是,它通常甚至更多*将来依赖它的东西,所以它变得越来越糟。一个选项可能是引入单独的列,并使组合编号成为计算列。 –

回答

4

我认为有效的方法是在使用劈裂列Order By

模式:

CREATE TABLE #TAB (VARCHARCOLUMN VARCHAR(20)) 
INSERT INTO #TAB 
SELECT '1060006-1' 
UNION ALL 
SELECT '1060006-10' 
UNION ALL 
SELECT '1060006-11' 
UNION ALL 
SELECT '1060006-12' 
UNION ALL 
SELECT '1060006-13' 
UNION ALL 
SELECT '1060006-15' 
UNION ALL 
SELECT '1060006-16' 
UNION ALL 
SELECT '1060006-17' 
UNION ALL 
SELECT '1060006-18' 
UNION ALL 
SELECT '1060006-19' 
UNION ALL 
SELECT '1060006-20' 
UNION ALL 
SELECT '1060006-2' 

现在,通过-并获得拆分份数的VARCHAR列订单

SELECT VARCHARCOLUMN 
,CAST(SUBSTRING(VARCHARCOLUMN,1,CHARINDEX('-', VARCHARCOLUMN)-1) AS BIGINT) AS PART1 
,CAST(SUBSTRING(VARCHARCOLUMN,CHARINDEX('-', VARCHARCOLUMN)+1,LEN(VARCHARCOLUMN)) AS INT) AS PART2 
FROM #TAB 
ORDER BY PART1, PART2 

这将返回

+---------------+---------+-------+ 
| VARCHARCOLUMN | PART1 | PART2 | 
+---------------+---------+-------+ 
| 1060006-1  | 1060006 |  1 | 
| 1060006-2  | 1060006 |  2 | 
| 1060006-10 | 1060006 | 10 | 
| 1060006-11 | 1060006 | 11 | 
| 1060006-12 | 1060006 | 12 | 
| 1060006-13 | 1060006 | 13 | 
| 1060006-15 | 1060006 | 15 | 
| 1060006-16 | 1060006 | 16 | 
| 1060006-17 | 1060006 | 17 | 
| 1060006-18 | 1060006 | 18 | 
| 1060006-19 | 1060006 | 19 | 
| 1060006-20 | 1060006 | 20 | 
+---------------+---------+-------+ 
1
ORDER BY 
CASE WHEN varcharcolumn like '%-%' THEN 1 ELSE 2 END, 
LEN(varcharcolumn), varcharcolumn 

这样你会得到那些有短线上方第一;那么LEN(XX)部分是这样的,1-10不会在1-10之后出现,而不需要转换为十进制。您可以随意删除按长度排序

如果您只想用短划线出现,那么也许您应该做一个where子句。

+0

似乎没有工作,上面添加了图片。 –

+0

我得到了您的预期输出。如果你只想要那些带有' - '的东西出现,你需要的是一个WHERE子句@JackReilly –

+0

我认为这种差异是因为你按照长度排序,并且当它们有相同的长度时让系统决定。我建议在'order by'子句中加入',varcharcolumn'。 –

0

Bennioe把我放在正确的道路上。最后,这让我获得了我想要的输出。

SELECT varcharcolumn 
FROM TableA 
order by LEN(varcharcolumn) asc, varcharcolumn asc 

enter image description here

+2

......只有当所有的字符串以相同的数字(例如1060006)开头时,它才起作用。 –

+2

您是否使用此数据测试过:'1060006-1','1060005-1','1060006-10','1060005-10'? –

+0

@ThorstenKettner短划线之后的数字是一个版本号,所以它不会正确吗? 1060006-1,1060006-2,1060007-1,1060007-2? –

相关问题