2017-09-30 178 views
1

此查詢短:應該避免使用子查詢和別名重複聚合函數嗎?

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

看來,這兩個查詢是等價的,除了缺乏的DESC

RANK() OVER(ORDER BY COUNT(*) DESC, ... 
中的第一個

。這可能是一個疏忽。

Postgres優化器應該爲這兩個查詢生成相同的計劃,因此請使用較短的一個。如果您有疑問,請執行EXPLAIN ANALYSE查詢並比較生成的計劃。

+0

抱歉,缺少DESC是一個錯字。我修復它。 – 91DarioDev