使用Case语句在SQL Server查询中排序

时间:2016-10-28 06:12:37

标签: sql sql-server tsql sorting

我有一个SQL查询,如下所示:

SELECT t.range  AS [Order Amount Range],
       Count(*) AS [Total Orders]
FROM   (SELECT CASE
                 WHEN totalamount BETWEEN 0 AND 49 THEN ' 0 - 49'
                 WHEN totalamount BETWEEN 50 AND 99 THEN ' 50 - 99'
                 WHEN totalamount BETWEEN 100 AND 149 THEN ' 100 - 149'
                 WHEN totalamount BETWEEN 150 AND 199 THEN ' 150 - 199'
                 WHEN totalamount BETWEEN 200 AND 249 THEN ' 200 - 249'
                 WHEN totalamount BETWEEN 250 AND 299 THEN ' 250 - 299'
                 WHEN totalamount BETWEEN 300 AND 349 THEN ' 300 - 349'
                 WHEN totalamount BETWEEN 350 AND 399 THEN ' 350 - 399'
                 WHEN totalamount BETWEEN 400 AND 449 THEN ' 400 - 449'
                 ELSE 'Above 500'
               END AS range
        FROM   [order]) t
GROUP  BY t.range
ORDER  BY t.range  

现在问题是排序不起作用,结果以任何特定的方式出现。因此第一行可能包含“0-49”范围,第二行包含“200-249”。

如何获得正常序列?

7 个答案:

答案 0 :(得分:0)

您可以使用以下查询获得正常序列。

 select t.range as [Order Amount Range], count(*) as [Total Orders] from(  
    select case                                                             
      when totalamount between 0 and 49    then ' 0 - 49'                  
      when totalamount between 50 and 99   then ' 50 - 99'                  
      when totalamount between 100 and 149 then ' 100 - 149'                  
      when totalamount between 150 and 199 then ' 150 - 199'                  
      when totalamount between 200 and 249 then ' 200 - 249'                  
      when totalamount between 250 and 299 then ' 250 - 299'                  
      when totalamount between 300 and 349 then ' 300 - 349'                  
      when totalamount between 350 and 399 then ' 350 - 399'                  
      when totalamount between 400 and 449 then ' 400 - 449'                  
      else 'Above 500' end as range  from [totalamount]) t 
      group by t.range

答案 1 :(得分:0)

列范围是varchar,SQL Server按字符串排序。字符1是在第五个之前

尝试将列的值而不是0-49放到00-049,而不是50-99 stavtiti 050-099,...

select t.range as [Order Amount Range], count(*) as [Total Orders] from
(  
select case                                                             
when totalamount between 0 and 49    then ' 000 - 049'                  
when totalamount between 50 and 99   then ' 050 - 099'                  
when totalamount between 100 and 149 then ' 100 - 149'                  
when totalamount between 150 and 199 then ' 150 - 199'                  
when totalamount between 200 and 249 then ' 200 - 249'                  
when totalamount between 250 and 299 then ' 250 - 299'                  
when totalamount between 300 and 349 then ' 300 - 349'                  
when totalamount between 350 and 399 then ' 350 - 399'                  
when totalamount between 400 and 449 then ' 400 - 449'                  
else ' Above 500' end as range  from [order]) t 
group by t.range order by t.range 

答案 2 :(得分:0)

您可以再举行一次加入,如下所示:

SELECT
    A.*
FROM
(   select t.range as [Order Amount Range], count(*) as [Total Orders] from
    (  
        select case                                                             
        when totalamount between 0 and 49    then '0 - 49'                  
        when totalamount between 50 and 99   then '50 - 99'                  
        when totalamount between 100 and 149 then '100 - 149'                  
        when totalamount between 150 and 199 then '150 - 199'                  
        when totalamount between 200 and 249 then '200 - 249'                  
        when totalamount between 250 and 299 then '250 - 299'                  
        when totalamount between 300 and 349 then '300 - 349'                  
        when totalamount between 350 and 399 then '350 - 399'                  
        when totalamount between 400 and 449 then '400 - 449'                  
        else 'Above 500' end as range  from [order]
    ) t 
    group by t.range
) A INNER JOIN 
(VALUES 
    (1, '0 - 49')   ,
    (2, '50 - 99')  ,
    (3, '100 - 149'),
    (4, '150 - 199'),
    (5, '200 - 249'),
    (6, '250 - 299'),
    (7, '300 - 349'),
    (8, '350 - 399'),
    (9, '400 - 449'),
    (10, 'Above 500')
) b(RowID, Title) ON A.[Order Amount Range] = b.Title

ORDER by b.RowID

答案 3 :(得分:0)

试一试这对你有用。

SELECT t.[range]  AS [Order Amount Range],
   Count(*) AS [Total Orders] 
   FROM(SELECT CASE
             WHEN totalamount BETWEEN 0 AND 49 THEN ' 0 - 49'
             WHEN totalamount BETWEEN 50 AND 99 THEN ' 50 - 99'
             WHEN totalamount BETWEEN 100 AND 149 THEN ' 100 - 149'
             WHEN totalamount BETWEEN 150 AND 199 THEN ' 150 - 199'
             WHEN totalamount BETWEEN 200 AND 249 THEN ' 200 - 249'
             WHEN totalamount BETWEEN 250 AND 299 THEN ' 250 - 299'
             WHEN totalamount BETWEEN 300 AND 349 THEN ' 300 - 349'
             WHEN totalamount BETWEEN 350 AND 399 THEN ' 350 - 399'
             WHEN totalamount BETWEEN 400 AND 449 THEN ' 400 - 449'
             ELSE 'Above 500'
           END AS [range]
    FROM   [order]) t INNER JOIN 
    (VALUES(1,' 0 - 49'),
           (2,' 50 - 99'),
           (3,' 100 - 149'),
           (4,' 150 - 199'),
           (5,' 200 - 249'),
           (6,' 250 - 299'),
           (7,' 300 - 349'),
           (8,' 350 - 399'),
           (9,' 400 - 449'),
           (10,'Above 500')
    )B (id,NewRange) on t.range=B.newrange
GROUP  BY t.[range],id
ORDER BY id

答案 4 :(得分:0)

使用一些编程而不是复制粘贴:

;with cteSource as
(
    select top 1000 row_number() over(order by (select 1)) as totalamount
    from master.dbo.spt_values v1
    cross join master.dbo.spt_values v2
),
cteSrcRanged as
(
    select
        src.totalamount,
        floor(src.totalamount / 50) amount_range
    from cteSource src
)
select
    src.totalamount,
    src.amount_range,
    case
        when src.amount_range >= 10
        then 'Above 500'
        else cast(src.amount_range * 50 as varchar(10)) + ' - ' + cast((src.amount_range + 1) * 50 - 1 as varchar(10))
    end range_name
from cteSrcRanged src

enter image description here

答案 5 :(得分:0)

您可以将[Order Amount Range]分解为CROSS APPLY,以便在整个陈述中使用。

对于排序,最简单的选择是使用已在数字上有用的[order].[totalamout]并正确匹配范围的顺序。

SELECT
    [range].[Order Amount Range],
    Count(*) AS [Total Orders]

FROM [order]

CROSS APPLY (
    SELECT
        CASE
            WHEN [order].[totalamount] BETWEEN 0 AND 49 THEN ' 0 - 49'
            WHEN [order].[totalamount] BETWEEN 50 AND 99 THEN ' 50 - 99'
            WHEN [order].[totalamount] BETWEEN 100 AND 149 THEN ' 100 - 149'
            WHEN [order].[totalamount] BETWEEN 150 AND 199 THEN ' 150 - 199'
            WHEN [order].[totalamount] BETWEEN 200 AND 249 THEN ' 200 - 249'
            WHEN [order].[totalamount] BETWEEN 250 AND 299 THEN ' 250 - 299'
            WHEN [order].[totalamount] BETWEEN 300 AND 349 THEN ' 300 - 349'
            WHEN [order].[totalamount] BETWEEN 350 AND 399 THEN ' 350 - 399'
            WHEN [order].[totalamount] BETWEEN 400 AND 449 THEN ' 400 - 449'
            ELSE 'Above 500'
        END AS [Order Amount Range]
    ) as [range]

GROUP  [range].[Order Amount Range]

ORDER  BY [order].[totalamount]

答案 6 :(得分:-1)

这真的很简单。

您只需要替换

ORDER  BY t.range

使用:

ORDER  BY CONVERT(INT,t.range)

就是这样。

希望它有所帮助。 :)