【问题标题】:Select the maximum rows of sorted subgroups选择已排序子组的最大行数
【发布时间】:2020-12-07 07:46:32
【问题描述】:

使用 PostgreSQL 11,我有一个表,其中包含每个月的每一天的 DAY 和 MONTH_TO_DAY 条目。我想为每个帐户选择最近的 MONTH_TO_DAY 条目。 我的桌子是:

+------+------------+--------------+------------+--------------------------+
|id    |account     |code          |interval    |timestamp                 |
+------+------------+--------------+------------+--------------------------+
|387276|ALPBls6EsP  |52            |MONTH_TO_DAY|2020-09-01 01:05:00.000000|
|387275|ALPBls6EsP  |52            |DAY         |2020-09-01 01:05:00.000000|
|387272|YkON8lk8A8  |25            |MONTH_TO_DAY|2020-09-01 01:05:00.000000|
|387271|YkON8lk8A8  |25            |DAY         |2020-08-01 01:05:00.000000|
|387273|ALPBls6EsP  |32            |MONTH_TO_DAY|2020-08-31 01:05:00.000000|
|387274|ALPBls6EsP  |32            |DAY         |2020-08-31 01:05:00.000000|
|387272|ALPBls6EsP  |27            |MONTH_TO_DAY|2020-08-30 01:05:00.000000|
|387271|ALPBls6EsP  |27            |DAY         |2020-08-30 01:05:00.000000|
+------+------------+--------------+------------+--------------------------+

如果有帮助,条目总是按时间降序排列。

在询问所有帐户的查询中,由于 31 日是 08 的最后一天,而 1 日是 09 的最新条目,我的预期输出是

+------+------------+--------------+------------+--------------------------+
|id    |account     |code          |interval    |timestamp                 |
+------+------------+--------------+------------+--------------------------+
|387276|ALPBls6EsP  |52            |MONTH_TO_DAY|2020-09-01 01:05:00.000000|
|387272|YkON8lk8A8  |25            |MONTH_TO_DAY|2020-09-01 01:05:00.000000|
|387273|ALPBls6EsP  |32            |MONTH_TO_DAY|2020-08-31 01:05:00.000000|
+------+------------+--------------+------------+--------------------------+

我想我想按月对条目进行分组(截断 dd/hh/ss),然后选择每个组中具有最大时间戳的行。我可以用这个获得正确的行,但我不知道如何获得任何其他字段。

SELECT max(timestamp) 
FROM mytable 
GROUP BY date_trunc('month', mytable.timestamp);

我还认为我可以在类似下面的内容上使用 distinct,但我对 distinct on 或 date_trunc 不太熟悉,我不知道如何将它们一起使用。

SELECT distinct on (timestamp)
    *
FROM mytable
ORDER BY date_trunc('month', mytable.timestamp)

【问题讨论】:

    标签: postgresql datetime max truncate distinct-on


    【解决方案1】:

    您确实需要distinct on,但您想将其应用于account

    select distinct on (account) *
      from mytable
     where interval = 'MONTH_TO_DAY'
     order by account, timestamp desc;
    

    如果你想要account month 的最新消息,那么这应该可以:

    select distinct on (date_trunc('month', timestamp), account) *
      from mytable
     where interval = 'MONTH_TO_DAY'
     order by date_trunc('month', timestamp), account, timestamp desc;
    

    【讨论】:

    • 除非我弄错了,否则这只给出每个帐户的最新行?而我需要每个帐户每月的最新行。
    • @blueberryscones 这正是您在顶部提出的问题。如果您也想要按月计算,请将date_trunc('month', timestamp) 添加到distinct on
    • 对不起,我试图尽可能清楚地回答这个问题。感谢您的回答。我将如何将 date_trunc 添加到 distinct on?创建select distinct on (account_code, date_trunc('month', timestamp)) * from network_usage where network_usage.interval = 'MONTH_TO_DAY' order by account_code, timestamp desc 给我一个错误,我一直在尝试将这些组合起来,不同的表达式必须匹配表达式的初始顺序。将 date_trunc 也放入订单中并不能修复它。为代码格式道歉,注释格式似乎不同。
    • @blueberryscones 您必须将date_trunc('month', timestamp) 包含在order by 中。我更新了我的答案。
    • @blueberryscones 不要听起来那么惊讶。它动摇了我的信心。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    相关资源
    最近更新 更多