sql - PostgreSQL - 加入最新记录以按结果分组

标签 sql postgresql

下面按预期工作,但你们有时可以在优化方面发挥神奇作用。这可以吗?还是可以用更好/更快的方式完成?

WITH last_events AS (
    SELECT DISTINCT ON (type, adid)
        type,
        adid,
        value,
        created_at
    FROM public.adid
    ORDER BY type, adid, created_at DESC
)
SELECT
    adid.type,
    adid.adid,
    count(*) as count,
    sum(adid.value) as summary,
    le.created_at
FROM public.adid
JOIN last_events le ON le.type = adid.type AND le.adid = adid.adid
GROUP BY adid.type, adid.adid, le.created_at
ORDER BY summary DESC, le.created_at DESC;

最佳答案

我认为您解决方案的某些部分是不必要的。 CTE 返回每个 (type,adid) 组的最大 created_at。主查询计算每个 (type,adid) 组的行数和每个 (type,adid) 组的 value 的总和。因此,可以这样写

SELECT
    adid.type,
    adid.adid,
    count(*) as count,
    sum(adid.value) as summary,
    max(adid.created_at) max_created_at
FROM public.adid
GROUP BY adid.type, adid.adid
ORDER BY summary DESC, max_created_at DESC;

如果您对与具有最高 created_at 的行对应的其他列感兴趣,那么您可以使用经典的每组最大方法之一。我更喜欢的一种方法是使用 GROUP BY 来找到最大值(与您的方法非常相似):

SELECT
    adid.type,
    adid.adid,
    t.count,
    t.summary,
    t.max_created_at,
    adid.value
FROM public.adid
JOIN (
  SELECT
    adid.type,
    adid.adid,
    count(*) as count,
    sum(adid.value) as summary,
    max(adid.created_at) max_created_at
  FROM public.adid
  GROUP BY adid.type, adid.adid
) t ON t.type = adid.type and 
       t.adid = adid.adid and 
       t.max_created_at = adid.created_at
ORDER BY t.summary DESC, t.max_created_at DESC;

我认为这样更好,因为我的解决方案只有一个聚合。您的解决方案在外部联接中使用 DISTINCT ON(隐藏聚合)和另一个 GROUP BY

找到每组最大数的另一种选择是使用窗口函数,但是,我认为聚合是解决您的问题的更好的解决方案,因为您需要更多的聚合值。此外,GROUP BY 似乎在 certain cases 中有更好的表现。比窗口函数。

关于sql - PostgreSQL - 加入最新记录以按结果分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47750974/

相关文章:

sql - MySQL 触发器问题

sql - 在流分析中将列逆透视为两个新列

database - Jhipster 和 Postgres 连接

java - 如何通过eclipse将postgres连接到heroku?

php - 使用求和函数时,我的查询返回单条记录

sql - 在哪里编辑 mysql 全文停用词列表?

c# - Entity Framework Core 很慢——如何让它更快?

sql - 如何将多行查询结果合并为一行

c# - 带有参数的mysql odbc插入

java - Postgresql:无法使用 EclipseLink 插入路径字段