Sql server 按T-SQL中值范围的数值分量排序
这种情况:Sql server 按T-SQL中值范围的数值分量排序,sql-server,tsql,Sql Server,Tsql,这种情况: create table #scores (score int) insert into #scores values (1) insert into #scores values (1) insert into #scores values (2) insert into #scores values (3) insert into #scores values (7) insert into #scores values (14) insert into #scores val
create table #scores (score int)
insert into #scores values (1)
insert into #scores values (1)
insert into #scores values (2)
insert into #scores values (3)
insert into #scores values (7)
insert into #scores values (14)
insert into #scores values (14)
;WITH Ranges AS
(
SELECT *
,CASE
WHEN score between 1 and 5
THEN '1-5'
WHEN score between 6 and 10
THEN '6-10'
WHEN score between 11 and 15
THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY ScoreRange
此数据中的结果:
Count ScoreRange
2 11-15
4 1-9
1 6-10
有没有一种简单的方法可以让数据按分数范围排序,就好像它是数字而不是字符串一样?那么先是1-5,然后是6-10,然后是11-15等等 在这种情况下,我就是这么做的。当您想要以所需的方式输出数据时,这非常有用,我个人将其用于报告输出或不具备任何排序能力的网格
;WITH Ranges AS
(
SELECT *
,CASE
WHEN score between 1 and 5
THEN '1-5'
WHEN score between 6 and 10
THEN '6-10'
WHEN score between 11 and 15
THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY LEN(ScoreRange),
ScoreRange
这就是我在这种情况下所做的。当您想要以所需的方式输出数据时,这非常有用,我个人将其用于报告输出或不具备任何排序能力的网格
;WITH Ranges AS
(
SELECT *
,CASE
WHEN score between 1 and 5
THEN '1-5'
WHEN score between 6 and 10
THEN '6-10'
WHEN score between 11 and 15
THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY LEN(ScoreRange),
ScoreRange
试试这个:
;WITH Ranges AS
(
SELECT *
,CASE
WHEN score between 1 and 5
THEN '1-5'
WHEN score between 6 and 10
THEN '6-10'
WHEN score between 11 and 15
THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY CASE ScoreRange
WHEN '1-5' THEN 1
WHEN '6-10' THEN 2
ELSE 3
END
试试这个:
;WITH Ranges AS
(
SELECT *
,CASE
WHEN score between 1 and 5
THEN '1-5'
WHEN score between 6 and 10
THEN '6-10'
WHEN score between 11 and 15
THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY CASE ScoreRange
WHEN '1-5' THEN 1
WHEN '6-10' THEN 2
ELSE 3
END
为什么不呢
按强制转换顺序(子字符串(ScoreRange,0,charindex('-',ScoreRange,0))作为INT)
试试这个
;WITH Ranges AS
(
SELECT *
,CASE
WHEN score between 1 and 5
THEN '1-5'
WHEN score between 6 and 10
THEN '6-10'
WHEN score between 11 and 15
THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY CAST(SUBSTRING(ScoreRange, 0, charindex('-', ScoreRange, 0)) AS INT)
为什么不呢
按强制转换顺序(子字符串(ScoreRange,0,charindex('-',ScoreRange,0))作为INT)
试试这个
;WITH Ranges AS
(
SELECT *
,CASE
WHEN score between 1 and 5
THEN '1-5'
WHEN score between 6 and 10
THEN '6-10'
WHEN score between 11 and 15
THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY CAST(SUBSTRING(ScoreRange, 0, charindex('-', ScoreRange, 0)) AS INT)
最简单的方法就是:
ORDER BY MIN(score)
也就是说,从范围中选择任意分数并按其顺序排列。最简单的方法是:
ORDER BY MIN(score)
也就是说,从范围中选择一个任意分数,并按其排序。因为
scoresrange
是一个字符串,我们可以使用字符串/单词排序而不是数字排序
在这种排序形式中,数字在字母和字符之前,因此11
在1-
和6-
之前,而1-
在6-
之前
这给了我们:
11-15
1-5
6-10
如果ScoreRange
值的前缀改为零(1-5->01-05)
排序会发生变化
使用相同的字符串/单词排序01-
位于05-
之前,05-
位于10-
之前
保留数字的语义(1
在5
之前,在10
之前),但这在字符串/单词比较下起作用
此方法适用于小于等于99的所有值;如果最大值更高,请添加额外的零:
001-005
006-010
011-015
016-100
101-999
您的查询现在变成:
;WITH Ranges AS
(
SELECT *,
CASE
WHEN score between 1 and 5 THEN '01-05'
WHEN score between 6 and 10 THEN '06-10'
WHEN score between 11 and 15 THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY ScoreRange
请参阅我的SQL FIDLE:因为
ScoreRange
是一个字符串,我们可以使用字符串/单词排序而不是数字排序
在这种排序形式中,数字在字母和字符之前,因此11
在1-
和6-
之前,而1-
在6-
之前
这给了我们:
11-15
1-5
6-10
如果ScoreRange
值的前缀改为零(1-5->01-05)
排序会发生变化
使用相同的字符串/单词排序01-
位于05-
之前,05-
位于10-
之前
保留数字的语义(1
在5
之前,在10
之前),但这在字符串/单词比较下起作用
此方法适用于小于等于99的所有值;如果最大值更高,请添加额外的零:
001-005
006-010
011-015
016-100
101-999
您的查询现在变成:
;WITH Ranges AS
(
SELECT *,
CASE
WHEN score between 1 and 5 THEN '01-05'
WHEN score between 6 and 10 THEN '06-10'
WHEN score between 11 and 15 THEN '11-15'
END AS ScoreRange
FROM #scores
)
SELECT Count = COUNT(*), ScoreRange
FROM Ranges
GROUP BY ScoreRange
ORDER BY ScoreRange
请参阅my SQL fiddle:因为
CTE
中已经有一个case语句,所以将ordering case语句也包含在其中是有意义的,让main select稍微干净一点,所有处理组的代码都放在一起。因为CTE
中已经有一个case语句,将ordering case语句也包含在其中是有意义的,让主select更干净一些,所有处理组的代码都放在一起。谢谢。我试图以类似的方式通过解析字符串并转换为INT来实现它,但我无法理解正确的逻辑。谢谢。我试着以类似的方式通过解析字符串并将其转换为INT,但我无法找出正确的逻辑。是否有理由不将1-5更改为01-05,将6-10更改为06-10?是否有理由不将1-5更改为01-05,将6-10更改为06-10?在我的特殊情况下,我必须匹配外部源中预先存在的范围,所以我不能用这个。但是+1是一个彻底的、解释得很好的、有用的答案。在我的特殊情况下,我必须匹配来自外部来源的预先存在的范围,所以我不能使用这个。但是+1是一个彻底的、解释得很好的、有用的答案。