范围Postgres中的总和日期

时间:2015-12-10 14:43:05

标签: sql postgresql

我有一个像这样定义的表:

CREATE TABLE Items (
    Barcode     CHAR(50)    PRIMARY KEY NOT NULL
    Location    CHAR(15)    ,
    ManufacturedAt  TIMESTAMP WITH TIMEZONE,
    ShippedOutAt    TIMESTAMP WITH TIMEZONE,
    ReceivedAt  TIMESTAMP WITH TIMEZONE,
    SoldAt      TIMESTAMP WITH TIMEZONE,
    DiscardedAt TIMESTAMP WITH TIMEZONE,
);

我正在尝试获取过去12个月内某个位置的每个日期字段的总和。 所以我试图获得的示例结果:

Date  NumManu NumShip NumRece NumSold NumDisc
DEC   5       3       3       2       1
NOV   3       5       5       3       2

我无论如何都不是SQL专家,但我不确定如何在不执行12个不同的sql查询(每月一个)的情况下执行此操作,或者这是唯一的方法吗?提前谢谢!

2 个答案:

答案 0 :(得分:0)

我可能会遗漏一些东西,但似乎你可以使用COUNT然后使用ORDER BY或GROUP BY月。

虽然我现在看到你只跟踪月份作为实际日期,所以你必须进行某种逻辑检查才能获得每月开始和结束之间的日期。

我认为如果是这种情况,你必须在where子句中手动记帐每个月。

答案 1 :(得分:0)

可以使用带有子选择(以及set-returning functions)的单个查询来完成:

SELECT  lo, hi, to_char(lo, 'MON') Date,
        (SELECT count(*) FROM Items WHERE ManufacturedAt BETWEEN lo AND hi) NumManu,
        (SELECT count(*) FROM Items WHERE ShippedOutAt   BETWEEN lo AND hi) NumShip,
        (SELECT count(*) FROM Items WHERE ReceivedAt     BETWEEN lo AND hi) NumRece,
        (SELECT count(*) FROM Items WHERE SoldAt         BETWEEN lo AND hi) NumSold,
        (SELECT count(*) FROM Items WHERE DiscardedAt    BETWEEN lo AND hi) NumDisc
FROM    generate_series(current_timestamp, current_timestamp - interval '11 mon', interval '-1 mon') ts,
LATERAL (select date_trunc('month', ts)) lo(lo),
LATERAL (select lo + interval '1 mon')   hi(hi)

...或同一个表的多个连接:

SELECT    lo, hi, to_char(lo, 'MON') Date,
          count(DISTINCT JManu) NumManu,
          count(DISTINCT JShip) NumShip,
          count(DISTINCT JRece) NumRece,
          count(DISTINCT JSold) NumSold,
          count(DISTINCT JDisc) NumDisc
FROM      generate_series(current_timestamp, current_timestamp - interval '11 mon', interval '-1 mon') ts,
LATERAL   (select date_trunc('month', ts)) lo(lo),
LATERAL   (select lo + interval '1 mon')   hi(hi)
LEFT JOIN Items JManu ON JManu.ManufacturedAt BETWEEN lo AND hi
LEFT JOIN Items JShip ON JShip.ShippedOutAt   BETWEEN lo AND hi
LEFT JOIN Items JRece ON JRece.ReceivedAt     BETWEEN lo AND hi
LEFT JOIN Items JSold ON JSold.SoldAt         BETWEEN lo AND hi
LEFT JOIN Items JDisc ON JDisc.DiscardedAt    BETWEEN lo AND hi
GROUP BY  lo, hi