使用Postgres 9.3.2,我希望按req_status
和req_time
分组customer_id
并为每个{0}返回一组 n 行customer_id
,即使req_status
计数为零。
req_time req_id customer_id req_status
-----------------------------------------------
2014-03-19 100 1 'FAILED'
2014-03-19 102 1 'FAILED'
2014-03-19 105 1 'OK'
2014-03-19 106 2 'FAILED'
2014-03-20 107 1 'OK'
2014-03-20 108 2 'FAILED'
2014-03-20 109 2 'OK'
2014-03-20 110 1 'OK'
输出
req_time customer_id req_status count
-------------------------------------------
2014-03-19 1 'FAILED' 2
2014-03-19 1 'OK' 1
2014-03-19 2 'FAILED' 1
2014-03-19 2 'OK' 0
2014-03-20 1 'FAILED' 0
2014-03-20 1 'OK' 2
2014-03-20 2 'FAILED' 1
2014-03-20 2 'OK' 1
我怎样才能做到这一点?
答案 0 :(得分:1)
要查看结果中缺少的行,请将左连接添加到可能行的完整网格。网格是由(req_time, customer_id, req_status)
与交叉连接的所有可能组合构建的:
SELECT d.req_time, c.customer_id, s.req_status, count(t.req_time) AS ct
FROM (
SELECT generate_series (min(req_time), max(req_time), '1 day')::date
FROM tbl
) d(req_time)
CROSS JOIN (SELECT DISTINCT customer_id FROM tbl) c(customer_id)
CROSS JOIN (VALUES ('FAILED'::text), ('OK')) s(req_status)
LEFT JOIN tbl t USING (req_time, customer_id, req_status)
GROUP BY 1,2,3
ORDER BY 1,2,3;
指望实际表中的一列,如果未找到匹配项将为0(NULL值不计算)。
假设req_time
为date
(不是timestamp
)。
这里类似的答案:
array_agg group by and null
答案 1 :(得分:1)
select
s.req_time, s.customer_id,
s.req_status,
count(t.req_status is not null or null) as "count"
from
t
right join (
(
select distinct customer_id, req_time
from t
) q
cross join
(values ('FAILED'), ('OK')) s(req_status)
) s on
t.req_status = s.req_status and
t.customer_id = s.customer_id and
t.req_time = s.req_time
group by 1, 2, 3
order by 1, 2, 3