Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 按T-SQL中值范围的数值分量排序_Sql Server_Tsql - Fatal编程技术网

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是一个彻底的、解释得很好的、有用的答案。