逐个案例导致SQL

时间:2012-01-25 06:24:58

标签: sql group-by sql-order-by

我有以下查询工作:

SELECT
COUNT(id), AgeRange
FROM
(
select
id,
case
when age < 0 then 'less than 0'
when age >= 0 and age <=30 then '0-30'
when age >= 31 and age <=60 then '31-60'
when age >= 61 and age <=90 then '61-90'
when age >= 91 then '91+'
when age = null then 'NO INFORMATION'
else 'no catagory'
end AS AgeRange
from queue 
where DATE between '01-Apr-2011' and '05-May-2011'
) T
GROUP BY
AgeRange;

现在我的要求是,我希望这些结果始终按顺序打印,首先小于0,而不是31-60,依此类推。

即使任何时间间隔的计数为0表示31-60。它应该在该间隔返回0。谁能帮忙。

进一步澄清:我想要的是,如果无论如何我得到零计数,它也应该打印出来。

在我的此查询的数据库表中,它没有显示小于0&#39;情况下:

COUNT(ID) AGERANGE       AGERANGESEQUENCE
-------------- -------------- ----------------
     11139 0-30                          2
      2292 31-60                         3
       329 61-90                         4
      1078 91+                           5
       746 NO INFORMATION                6

它没有显示第0行的第0行。

我也想要这样,这样我就可以得到一个定义良好的表结构。

3 个答案:

答案 0 :(得分:2)

SELECT coalesce(t.idcount, 0),
       c.agerangetext
FROM   (SELECT 1, 'less than 0' UNION ALL
        SELECT 2, '0-30'        UNION ALL
        SELECT 3, '31-60'       UNION ALL
        SELECT 4, '61-90'       UNION ALL
        SELECT 5, '91+'         UNION ALL
        SELECT 6, 'NO INFORMATION'
       ) AS c(agerange, agerangetext)
  LEFT OUTER JOIN (SELECT COUNT(id) AS idcount,
                          agerange
                   FROM   (SELECT id,
                                  CASE
                                    WHEN age < 0 THEN 1
                                    WHEN age >= 0 AND age <= 30 THEN 2
                                    WHEN age >= 31 AND age <= 60 THEN 3
                                    WHEN age >= 61 AND age <= 90 THEN 4
                                    WHEN age >= 91 THEN 5 
                                    WHEN age IS NULL THEN 6
                                  END AS agerange
                           FROM   QUEUE
                           WHERE  DATE BETWEEN '01-Apr-2011' AND '05-May-2011'
                          ) t
                   GROUP  BY agerange) AS t
    ON c.agerange = t.agerange
ORDER  BY c.agerange  

Working sample

答案 1 :(得分:1)

如果您想按该列订购 - 只需添加

即可
ORDER BY AgeRange

GROUP BY AgeRange子句之后:

SELECT
   COUNT(id), AgeRange
FROM
   ( ..... ) T
GROUP BY
    AgeRange
ORDER BY
    AgeRange

如果该序列不适合您,那么您必须添加第二个CASE语句来定义内部选择的AgeRangeSequence,然后按该列排序:

SELECT
     COUNT(id), AgeRange, AgeRangeSequence
FROM
     (SELECT
          id,
          CASE
             WHEN age < 0 THEN 'less than 0'
             WHEN age >= 0 AND age <= 30 THEN '0-30'
             WHEN age >= 31 AND age <= 60 THEN '31-60'
             WHEN age >= 61 AND age <= 90 THEN '61-90'
             WHEN age >= 91 THEN '91+'
             WHEN age IS NULL THEN 'NO INFORMATION'
             ELSE 'no category'
          END AS AgeRange,
          CASE
             WHEN age < 0 THEN 1
             WHEN age >= 0 AND age <= 30 THEN 2
             WHEN age >= 31 AND age <= 60 THEN 3
             WHEN age >= 61 AND age <= 90 THEN 4
             WHEN age >= 91 THEN 5
             WHEN age IS NULL THEN 6   
             ELSE 7
           END AS AgeRangeSequence,
    FROM dbo.queue 
    WHERE [DATE] BETWEEN '01-Apr-2011' AND '05-May-2011'
   ) T
GROUP BY
    AgeRange, AgeRangeSequence
ORDER BY
    AgeRangeSequence

PS:在CASE声明中,您应检查WHEN age IS NULL使用WHEN age = NULL,因为您无法与NULL进行比较正常比较运算符!

答案 2 :(得分:0)

一种方法是使用一堆UNION:

SELECT 1, COUNT(id), 'less than 0'
FROM queue
WHERE age < 0 AND DATE BETWEEN '01-Apr-2011' and '05-May-2011'
UNION
SELECT 2, COUNT(id), '0-30'
FROM queue
WHERE age BETWEEN 0 AND 30 AND DATE between '01-Apr-2011' and '05-May-2011'
UNION
...