生成系列Postgres

时间:2019-03-21 06:12:27

标签: postgresql

我希望能够按天,周,月或根据我设置的间隔生成行组

solution之后,它适用于按月划分的粒度。但是尝试间隔1周,则不会返回任何记录。

这是我桌子上的行

enter image description here

这是我每月每个间隔的当前查询,效果很好。

SELECT *
FROM  (
   SELECT  day::date
   FROM   generate_series(timestamp '2018-09-01'
                        , timestamp '2018-12-01'
                        , interval  '1 month') day
   ) d
LEFT   JOIN (
   SELECT date_trunc('month', created_date)::date AS day
        , SUM(escrow_amount) AS profit, sum(total_amount) as revenue
   FROM   (
   select distinct on (order_id) order_id, escrow_amount, total_amount, create_time from order_item
   WHERE  created_date >= date '2018-09-01'
   AND    created_date <= date '2018-12-01'
-- AND    ... more conditions

   ) t2 GROUP  BY 1
   ) t USING (day)
ORDER  BY day;

此查询的结果

enter image description here

这是每周间隔查询。为简便起见,我将范围减少到两个月。

SELECT *
FROM  (
   SELECT  day::date
   FROM   generate_series(timestamp '2018-09-01'
                        , timestamp '2018-11-01'
                        , interval  '1 week') day
   ) d
LEFT   JOIN (
   SELECT date_trunc('week', created_date)::date AS day
        , SUM(escrow_amount) AS profit, sum(total_amount) as revenue
   FROM   (
   select distinct on (order_id) order_id, escrow_amount, total_amount, create_time from order_item
   WHERE  created_date >= date '2018-09-01'
   AND    created_date <= date '2018-11-01'
-- AND    ... more conditions

   ) t2 GROUP  BY 1
   ) t USING (day)
ORDER  BY day;

请注意,我有10月的记录,但是此处的结果未显示10月的日期。

enter image description here

知道我在这里缺少什么吗?

1 个答案:

答案 0 :(得分:2)

您的第一个查询结果不会被截断到一周的开始。

date_trunc('2018-09-01'::date, 'week')::date

等于

'2018-08-27'::date

因此您一天的加入无法正常工作

'2018-09-01'::date <> '2018-08-27'::date

您的查询应类似于:

SELECT *
FROM  (
   SELECT  day::date
   FROM   generate_series(date_trunc('week',timestamp '2018-09-01') --series begin trunc
                        , timestamp '2018-11-01'
                        , interval  '1 week') day
   ) d
LEFT   JOIN (
   SELECT date_trunc('week', created_date::date)::date AS day
        , SUM(escrow_amount) AS profit, sum(total_amount) as revenue
   FROM   (
   select distinct on (order_id) order_id, escrow_amount, total_amount, create_time from order_item
   WHERE  created_date::date >= date '2018-09-01'
   AND    created_date::date <= date '2018-11-01'
-- AND    ... more conditions

   ) t2 GROUP  BY 1
   ) t USING (day)
WHERE day >= '2018-09-01' --to skip days from begining of the week to the begining of the series before trunc
ORDER  BY day;