PostgreSQL:使用Generate_Series()计数0
我试图统计过去7天的记录,包括那些没有任何记录或0的记录。这是我目前的问题PostgreSQL:使用Generate_Series()计数0,sql,postgresql,group-by,count,generate-series,Sql,Postgresql,Group By,Count,Generate Series,我试图统计过去7天的记录,包括那些没有任何记录或0的记录。这是我目前的问题 WITH calendar as ( SELECT d FROM generate_series(date_trunc('day',CURRENT_DATE - '7 day'::interval - '7 hour'::interval),date_trunc('day', CURRENT_DATE - INTERVAL '7 hour'), '1 day'::interval) d ) SELECT
WITH calendar as (
SELECT d
FROM generate_series(date_trunc('day',CURRENT_DATE - '7 day'::interval - '7 hour'::interval),date_trunc('day', CURRENT_DATE - INTERVAL '7 hour'), '1 day'::interval) d
)
SELECT
COUNT(mc.id),
mc.name AS ord_name,
c.d::date AS ord_date
FROM test_table mc
LEFT JOIN calendar c
ON c.d = mc.occured_at::date
WHERE date_trunc('day', occured_at - interval '7 hour') >
(CURRENT_DATE + INTERVAL '7 hour') - INTERVAL '7 days'
GROUP BY
name,
c.d
ORDER BY
c.d;
我的查询结果与
所以我使用generate_系列来获取我想要的日期。我减去7小时,因为从技术上讲,一天从早上7点开始,到第二天早上6点59分结束。我使用LEFT JOIN来比较我从日历中获得的日期和我的表的日期
样本数据:测试表
预期结果:
顺便说一句,use calendar table in left btw order是关键字,所以最好不要使用任何关键字作为表名,因为您已经使用过了,所以请使用双引号
WITH calendar as (
SELECT d
FROM generate_series(date_trunc('day',CURRENT_DATE - '7 day'::interval - '7 hour'::interval),date_trunc('day', CURRENT_DATE - INTERVAL '7 hour'), '1 day'::interval) d
)
SELECT
COUNT(mc.id),
mc.name AS ord_name,
c.d::date AS ord_date
FROM
calendar c LEFT JOIN
"order" mc
ON c.d = mc.occured_at::date
WHERE date_trunc('day', occured_at - interval '7 hour') >
(CURRENT_DATE + INTERVAL '7 hour') - INTERVAL '7 days'
GROUP BY
name,
c.d
ORDER BY
c.d;
使用交叉联接生成所有行,然后使用左联接引入具有匹配值的行:
WITH calendar as (
SELECT d
FROM generate_series(date_trunc('day', CURRENT_DATE - '7 day'::interval - '7 hour'::interval),
date_trunc('day', CURRENT_DATE - INTERVAL '7 hour'),
'1 day'::interval
) d
)
SELECT n.name AS ord_name,
c.d::date AS ord_date
COUNT(mc.id),
FROM (SELECT DISTINCT mc.name test_table mc) n CROSS JOIN
calendar c LEFT JOIN
test_table mc
ON mc.occured_at >= c.d - interval '7 hour' and
mc.occured_at < c.d + interval '1 day' - interval '7 hour'
GROUP BY n.name, c.d
ORDER BY c.d, n.name;
谢谢你的回答Zaynul,显然我已经试过了,但我仍然错过了一些日期。@Paolo你丢失的日期数据我编辑了我的问题,并添加了一个DB FIDLE链接,其中包含示例数据。嘿,戈登,谢谢你的回答。现在所有的日期都显示出来了,我唯一担心的是查询会统计当天上午12点到晚上11点59分的记录。有没有可能把这段时间调整到第二天早上7点到6点59分。您可以通过比较中的日期算术来解决这个问题。
WITH calendar as (
SELECT d
FROM generate_series(date_trunc('day',CURRENT_DATE - '7 day'::interval - '7 hour'::interval),date_trunc('day', CURRENT_DATE - INTERVAL '7 hour'), '1 day'::interval) d
)
SELECT
COUNT(mc.id),
mc.name AS ord_name,
c.d::date AS ord_date
FROM
calendar c LEFT JOIN
"order" mc
ON c.d = mc.occured_at::date
WHERE date_trunc('day', occured_at - interval '7 hour') >
(CURRENT_DATE + INTERVAL '7 hour') - INTERVAL '7 days'
GROUP BY
name,
c.d
ORDER BY
c.d;
WITH calendar as (
SELECT d
FROM generate_series(date_trunc('day', CURRENT_DATE - '7 day'::interval - '7 hour'::interval),
date_trunc('day', CURRENT_DATE - INTERVAL '7 hour'),
'1 day'::interval
) d
)
SELECT n.name AS ord_name,
c.d::date AS ord_date
COUNT(mc.id),
FROM (SELECT DISTINCT mc.name test_table mc) n CROSS JOIN
calendar c LEFT JOIN
test_table mc
ON mc.occured_at >= c.d - interval '7 hour' and
mc.occured_at < c.d + interval '1 day' - interval '7 hour'
GROUP BY n.name, c.d
ORDER BY c.d, n.name;