【问题标题】:Postgres query - 24 hour time series filtered by specific column, but still return row for each hourPostgres 查询 - 按特定列过滤的 24 小时时间序列,但仍返回每个小时的行
【发布时间】:2020-11-02 01:45:38
【问题描述】:

我正在处理一个查询,该查询返回给定日期的每小时时间序列,但我需要按另一个表上的特定列进行过滤,在我的例子中是用户 ID。

这是我当前的查询,它返回当天每个小时的提交计数:

SELECT hours, count(s.id)
FROM generate_series(current_date, current_date + interval '23h', cast('1h' as interval)) hours
         left join submission s on hours = date_trunc('hour', s.submitted_date)
group by hours
order by hours;

但是,这些记录与用户 ID 无关,因此当我使用这样的查询按用户 ID 过滤时,它只会返回收到该用户提交的小时数,而我需要它返回每个用户的记录小时很像上面的查询:

SELECT hours, count(s.id)
FROM generate_series(current_date, current_date + interval '23h', cast('1h' as interval)) hours
    left join submission s on hours = date_trunc('hour', s.submitted_date)
    left join form f on s.form_custom_id = f.custom_id
    left join "user" u on f.user_id = u.id
    where u.id = 4
group by hours
order by hours;

这是我的 SQL Fiddle:http://www.sqlfiddle.com/#!17/a8d80/1

任何帮助将不胜感激!

【问题讨论】:

  • use text, not images/links, for text--including tables & ERDs。仅将图像用于无法表达为文本或增强文本的内容。在图像中包含图例/键和说明。将需要询问的内容放在您的帖子中,而不仅仅是在链接/小提琴中。 minimal reproducible example 包括剪切 & 粘贴 & 可运行代码,包括作为代码输入的最小代表性示例;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。说明您可以做什么以及它们与您的目标有何关系。

标签: sql postgresql date time-series left-join


【解决方案1】:

您希望将用户的过滤条件移动到联接的on 端。因此,您需要从user 表中计算一列,因此要考虑过滤逻辑:

select hours, count(u.id)
from generate_series(current_date, current_date + interval '23h', cast('1h' as interval)) hours
left join submission s on hours = date_trunc('hour', s.submitted_date)
left join form f on s.form_custom_id = f.custom_id
left join "user" u on f.user_id = u.id and u.id = 4
group by hours
order by hours;

【讨论】:

  • 这成功了,这是多么微妙但重要的区别。非常感谢!
【解决方案2】:

对于left join,对除第一个表之外的所有表的过滤需要在on 子句中:

select hours, count(s.id)
from generate_series(current_date, current_date + interval '23h', cast('1h' as interval)) hours left j oin
     submission s 
     on hours = date_trunc('hour', s.submitted_date) left join
     form f
     on s.form_custom_id = f.custom_id left join
     "user" u
     on f.user_id = u.id and u.id = 4
group by hours
order by hours;

否则,where 子句将过滤掉不匹配的行,将外连接变为内连接。

【讨论】:

  • 感谢您的快速回复。使用您的示例后,无论用户身份如何,它似乎仍然返回记录。
猜你喜欢
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
  • 1970-01-01
  • 2021-01-17
  • 1970-01-01
相关资源
最近更新 更多