是否应该通过使用子查询和别名来避免重复聚合函数?

时间:2017-09-30 11:30:36

标签: sql postgresql aggregate-functions

此查询更短:

    SELECT  main.num_msgs, main.num_grps, main.rnk
FROM (
SELECT
        user_id,
        COUNT(distinct group_id) AS num_grps,
        COUNT(*)                 AS num_msgs,
    RANK() OVER(ORDER BY COUNT(*)DESC, COUNT(distinct group_id) DESC, user_id DESC) rnk
FROM messages
    WHERE message_date > date_trunc('week', now())
    GROUP BY user_id
) AS main
WHERE main.user_id = %s

给了我更长时间的结果:

SELECT  main.num_msgs, main.num_grps, main.rnk
FROM (
SELECT
    user_id,
    num_grps,
    num_msgs,
    RANK() OVER(ORDER BY num_msgs DESC, num_grps DESC, user_id DESC) rnk
FROM (
    SELECT
        user_id,
        COUNT(distinct group_id) AS num_grps,
        COUNT(*)                 AS num_msgs
    FROM messages
    WHERE message_date > date_trunc('week', now())
    GROUP BY user_id
    ) AS sub
) AS main
WHERE main.user_id = %s

第二个更长,因为它使用另一个子查询,这样可以避免使用别名重复PARTITION BY中的聚合函数,而第一个更短并且没有子查询但重复聚合函数,因为它不能使用别名。

更喜欢哪种方式?

1 个答案:

答案 0 :(得分:1)

似乎两个查询都是等价的,除了缺少DESC

RANK() OVER(ORDER BY COUNT(*) DESC, ...

在第一个。这可能是一种疏忽。

Postgres优化器应为两个查询生成相同的计划,因此请使用较短的查询。如果您有疑问,请为查询执行EXPLAIN ANALYSE并比较生成的计划。