在T-SQL中按值范围的数字组件排序

时间:2014-07-15 10:57:02

标签: 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 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

有没有一种简单的方法可以让ScoreRange对数据进行排序,好像它是数字而不是字符串?那么首先是1-5,然后是6-10,然后是11-15,依此类推?

5 个答案:

答案 0 :(得分:1)

这就是我在这样的情况下所做的。当你想以你想要的方式输出数据时非常有用,我个人用它来报告输出或者没有任何排序能力的网格。

;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

答案 1 :(得分:1)

为什么不

<强> ORDER BY CAST(SUBSTRING(ScoreRange, 0, charindex('-', ScoreRange, 0)) AS 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)

<强> FIDDLE DEMO

答案 2 :(得分:1)

最简单的方法就是:

ORDER BY MIN(score)

即,从该范围中选择一个任意分数,然后按顺序选择。

答案 3 :(得分:1)

因为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

请参阅我的SQL小提琴:http://sqlfiddle.com/#!3/f0699/2/0

答案 4 :(得分:0)

试试这个:

;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