跨数组值扩展结果集

时间:2019-04-16 09:38:10

标签: postgresql join group-by

我正在运行一些报告查询,我想在4周的特定时间内扩展每条记录的结果。

这是当前查询:

select
  job_id,
  week,
  count(*),
  sum(count(*)) over (partition by job_id)
from candidates
group by job_id, week

当前结果

 job_id | week | count | sum 
--------+------+-------+------
   3258 |    1 |    21 |  23 
   3258 |    2 |     2 |  23 
   3259 |    1 |     1 |   4 
   3259 |    4 |     1 |   4 

但理想情况下,我想扩展4周的特定范围:

所需结果

 job_id | week | count | sum 
--------+------+-------+-----
   3258 |    1 |    21 |  23 
   3258 |    2 |     2 |  23 
   3258 |    3 |     0 |  23 # added row with 0 count
   3258 |    4 |     0 |  23 # added row with 0 count
   3259 |    1 |     1 |   4 
   3259 |    2 |     0 |   4 # added row with 0 count
   3259 |    3 |     0 |   4 # added row with 0 count
   3259 |    4 |     1 |   4 

使用左联接不会返回预期的结果,如您在此SQL fiddle

中所见

模式(PostgreSQL v9.6)

CREATE TABLE candidates(
   job_id integer,
   week integer,
   count1 integer,
   sum1 integer
);

INSERT INTO candidates(job_id, week, count1, sum1) VALUES (3984, 1, 13, 26);
INSERT INTO candidates(job_id, week, count1, sum1) VALUES (3984, 2, 13, 26);

INSERT INTO candidates(job_id, week, count1, sum1) VALUES (3985, 1, 42, 46);
INSERT INTO candidates(job_id, week, count1, sum1) VALUES (3985, 4, 3, 46);

查询#1

select
  c.job_id,
  weeks.week_nr as week,
  c.count1,
  c.sum1
from generate_series(1,4) as weeks(week_nr)
left join candidates c on c.week = weeks.week_nr 
order by c.job_id, week;
| job_id | week | count | sum |
| ------ | ---- | ----- | --- |
| 3984   | 1    | 1     | 2   |
| 3984   | 2    | 1     | 2   |
| 3985   | 1    | 1     | 2   |
| 3985   | 4    | 1     | 2   |
| null   | 3    | null  | null|

1 个答案:

答案 0 :(得分:0)

在Postgresql中,我们可以使用 generate_series()(或)其中条件

 select job_id,week,count(*),sum(count(*)) over (partition by job_id)
 from generate_series(1,4) as weeks(week_nr)
 left join candidates c on c.week = weeks.week_nr 
 group by job_id, week order by job_id,week;

                       (or)

 select job_id,week,count(*),sum(count(*)) over (partition by job_id)
 from candidates where week>=1 and week<=4
 group by job_id, week;