sql - 如何显示一年中每周发生的行?

标签 sql postgresql timestamp aggregate

我正在尝试解析 PostgreSQL 9.5 中的日志表。假设我正在记录从属于我公司的所有电话发送的短信。对于每条记录,我都有一个时间戳和手机 ID。
我想显示每周发送了多少条短信,但仅限于一年中每周发送短信的手机。

我的表格如下:

╔════════════╦══════════╗
║ event_date ║ phone_id ║
╠════════════╬══════════╣
║ 2016-01-05 ║    1     ║
║ 2016-01-06 ║    2     ║
║ 2016-01-13 ║    1     ║
║ 2016-01-14 ║    1     ║
║ 2016-01-14 ║    3     ║
║ 2016-01-20 ║    1     ║
║ 2016-01-21 ║    1     ║
║ 2016-01-22 ║    2     ║
╚════════════╩══════════╝

我想要下面的显示

╔══════════════╦══════════╦══════════════╗
║ week_of_year ║ phone_id ║ count_events ║
╠══════════════╬══════════╬══════════════╣
║  2016-01-04  ║    1     ║       1      ║
║  2016-01-11  ║    1     ║       2      ║
║  2016-01-18  ║    1     ║       2      ║
╚══════════════╩══════════╩══════════════╝

仅显示 phone_id 1,因为这是一年中每周唯一具有事件的 ID。

现在,我可以查询按 week_of_year 和 phone_ID 分组。我得到以下结果:

╔══════════════╦══════════╦══════════════╗
║ week_of_year ║ phone_id ║ count_events ║
╠══════════════╬══════════╬══════════════╣
║  2016-01-04  ║    1     ║       1      ║
║  2016-01-04  ║    2     ║       1      ║
║  2016-01-11  ║    1     ║       2      ║
║  2016-01-11  ║    3     ║       1      ║
║  2016-01-18  ║    1     ║       2      ║
║  2016-01-18  ║    2     ║       1      ║
╚══════════════╩══════════╩══════════════╝

如何进行过滤以仅保留一年中每周出现的 phone_id?我尝试了各种子查询,但我必须承认我被卡住了。 :-)

关于 week_of_year 的定义:因为我想每周合并数据,所以我在我的选择中使用:date_trunc('week', event_date)::date as interval。然后我按 interval 分组以获得每周每个 phone_id 的短信数量。

关于日期范围,我只想从 2016 年开始,我在查询中使用 where 条件来忽略之前的所有内容:WHERE event_date > '2016-01-01'

我看到了创建 SQL Fiddle 的请求,但我在这样做时遇到了问题,如果我不够幸运,没有很好的提示来解决这个问题,我会这样做。

创建了一个 quick SQL Fiddle ,希望它有用。

最佳答案

您的年份概念似乎很模糊。让我假设您的意思是在一段时间内超出您的数据范围。

with w as (
      select date_trunc('week', event_date) as wk, phone_id, count(*) as cnt
      from messages
      group by 1, 2
     ),
     ww as (
      select w.*,
             min(wk) over () as min_wk,
             max(wk) over () as max_wk,
             count(*) over (partition by phone_id) as numweeks
      from w
     )
select ww.wk, ww.phone_id, ww.cnt
from ww
where (max_wk - min_wk) / 7 = cnt - 1;

第一个 CTE 只是按周和手机 ID 聚合数据。第二个 CTE 计算数据中的第一周和最后一周(这些可以用常量替换),以及给定手机的周数。

最后,where 子句确保周数跨越时间段。

关于sql - 如何显示一年中每周发生的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36322180/

相关文章:

sql - Zend 如何创建左连接

sql - T-SQL 四舍五入到小数位

Postgresql 函数返回多个选择语句

python - Web2py DAL 查找最新日期的记录

postgresql - ActiveRecord find_or_initialize_by 竞争条件

mysql - 关于 MySQL 创建时间戳的 ORMLite 问题

c - 如何在linux内核中找到中断源代码?

jenkins - 什么会导致控制台 View 和 blueocean View 之间的时间戳不同?

mysql - 搜索满足 Column1 <= X <= Column2 的行的 SQL 查询非常慢

sql - Microsoft Dynamics SQL 中的日期部分函数错误