以下按预期工作,但在优化方面,你们有时可以做出魔术。这是正确的还是可以更好/更快的方式完成?
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;
答案 0 :(得分:2)
我相信解决方案的某些部分是不必要的。 CTE每created_at
组返回最多(type,adid)
个。主查询计算每(type,adid)
组的行数和value
每(type,adid)
组的总和。因此,它可以这样写成
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中比窗口函数具有更好的性能。