是否可以在一个查询中按不同条件计数?

时间:2016-02-10 08:52:08

标签: sql postgresql

我有一个Shipments表,其中基本上包含日期

的货件数据

id为integer datehipped是date

id    dateshipped
1     1-JAN-16
2     1-JAN-16
3     3-FEB-16
4     9-FEB-16  

我想写一个查询,根据Months计算所有货件。 我应该得到的是:

Jan  Feb  March....
2     2     0

我知道我可以通过查询每一列来实现它,只获得这个特定月份的相关行并计算它们。

如下:

Select     (Select count(*)
           from Shipments
           Where EXTRACT(YEAR FROM dateshipped)::int=2016 and EXTRACT(MONTH FROM dateshipped)::int=1 )as JAN,
           (Select count(*)
           from Shipments
           Where EXTRACT(YEAR FROM dateshipped)::int=2016 and EXTRACT(MONTH FROM dateshipped)::int=2 )as FEB

但是它的代码太多了......

如果可以使用单个FROM语句进行操作,并且每列都会获得它自己的相关行数,那么我很想知道。

类似的东西:

Select COL1,COL2,COL3...
from Shipments
Where EXTRACT(YEAR FROM dateshipped)::int=2016;

并且有类似的内容:

COL1 = count only JAN records
COL2 = count only FEB records
....

或许在几个月或其他任何解决方案上都有Parations的东西?

3 个答案:

答案 0 :(得分:3)

您需要一个透视查询来完成此任务:

SELECT SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 1  THEN 1 ELSE 0 END) AS Jan,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 2  THEN 1 ELSE 0 END) AS Feb,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 3  THEN 1 ELSE 0 END) AS Mar,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 4  THEN 1 ELSE 0 END) AS Apr,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 5  THEN 1 ELSE 0 END) AS May,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 6  THEN 1 ELSE 0 END) AS Jun,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 7  THEN 1 ELSE 0 END) AS Jul,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 8  THEN 1 ELSE 0 END) AS Aug,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 9  THEN 1 ELSE 0 END) AS Sep,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 10 THEN 1 ELSE 0 END) AS Oct,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 11 THEN 1 ELSE 0 END) AS Nov,
       SUM(CASE WHEN EXTRACT(MONTH FROM dateshipped)::int = 12 THEN 1 ELSE 0 END) AS Dec
FROM Shipments
WHERE EXTRACT(YEAR FROM dateshipped)::int=2016

答案 1 :(得分:3)

自9.4起,您可以使用FILTER

SELECT
    count(*) AS total,
    count(*) FILTER (WHERE Extract(MONTH FROM dateshipped)::int=1) AS JAN,
    count(*) FILTER (WHERE Extract(MONTH FROM dateshipped)::int=2) AS FEB,
    ...
FROM Shipments
WHERE Extract(YEAR FROM dateshipped)::int=2016;

答案 2 :(得分:2)

尝试使用sum函数:

Select 
   sum(case when extract(MONTH from dateshipped)=1 then 1 else 0 end) as jan,
   sum(case when extract(MONTH from dateshipped)=2 then 1 else 0 end) as feb,
   sum(case when extract(MONTH from dateshipped)=3 then 1 else 0 end) as march
   .....
   .....
from Shipments
Where EXTRACT(YEAR FROM dateshipped)::int=2016;