2012-12-16 51 views
2

獲得最高值用下面的查詢刪除行重複和PostgreSQL的

SELECT 
    users.id, 
    users.username, 
    users.email, 
    groups.permission 
FROM users 
INNER JOIN memberships ON users.id = memberships.user_id 
INNER JOIN groups ON memberships.group_id = groups.id 
INNER JOIN groupings ON groups.id = groupings.group_id 
WHERE groupings.repo_id = 1 
GROUP BY users.id, groups.permission 
ORDER BY users.id 

我得到以下行:

----+---------------------------+-----------------------------------------+------------ 
id |   username   |     email     | permission 
----+---------------------------+-----------------------------------------+------------ 
    2 | viva_leuschke0   | [email protected] | 1 
    2 | viva_leuschke0   | [email protected] | 2 
    3 | loyce_herman1    | [email protected]    | 1 
    3 | loyce_herman1    | [email protected]    | 3 
    4 | verona_vandervort2  | [email protected]   | 1 
    4 | verona_vandervort2  | [email protected]   | 2 
    4 | verona_vandervort2  | [email protected]   | 3 
    5 | bruen3_ms_hans   | [email protected]   | 1 
    5 | bruen3_ms_hans   | [email protected]   | 2 
    5 | bruen3_ms_hans   | [email protected]   | 3 
----+---------------------------+-----------------------------------------+------------ 

的問題是:我怎麼可以調整該查詢返回唯一行,按最高權限值進行篩選?例如:

----+---------------------------+-----------------------------------------+------------ 
id |   username   |     email     | permission 
----+---------------------------+-----------------------------------------+------------ 
    2 | viva_leuschke0   | [email protected] | 2 
    3 | loyce_herman1    | [email protected]    | 3 
    4 | verona_vandervort2  | [email protected]   | 3 
    5 | bruen3_ms_hans   | [email protected]   | 3 
----+---------------------------+-----------------------------------------+------------ 

我使用的是PostgreSQL 9.1。

更新:通過使用DISTINCT ON條款,我能夠得到我想要的。

SELECT DISTINCT ON(users.id) 
    users.id, 
    users.username, 
    users.email, 
    groups.permission 
FROM users 
INNER JOIN memberships ON users.id = memberships.user_id 
INNER JOIN groups ON memberships.group_id = groups.id 
INNER JOIN groupings ON groups.id = groupings.group_id 
WHERE groupings.repo_id = 1 
GROUP BY users.id, groups.permission 
ORDER BY 
    users.id ASC, 
    groups.permission DESC 

這是做這件事的最好方法嗎?

+0

我想你張貼(有效!)回答您發現爲*答案*和接受它。這是推薦的方式:你可以回答你自己的問題。 –

+0

Hehehehehe ...實際上,我問的是這個問題是否是最好的。 –

+0

好像我錯過了兩件事。您添加的問題和您添加的查詢中的不完善之處。很好,乾淨的問題,順便說一句。 –

回答

1

在仔細檢查,查詢可以(也應該)加以改進:


SELECT DISTINCT ON (u.id) 
     ,u.id 
     ,u.username 
     ,u.email 
     ,g.permission 
FROM users  u 
JOIN memberships m ON m.user_id = u.id 
JOIN groups  g ON g.id = m.group_id 
JOIN groupings gi ON gi.group_id = g.id 
WHERE gi.repo_id = 1 

             
  
    GROUP BY u.id, g.permission 
   
ORDER BY u.id, g.permission DESC 

GROUP BY是沒有用的。 DISTINCT ON獨自給你一個獨特的users.id。刪除GROUP BY,你會得到相同的結果,只是更快。

您可能要添加更多的列到ORDER BY來決定選擇哪一行,其中一個以上的每id佔有率最高的permission。你擁有它的方式,你會得到這個案例的任意選擇(假設它可能發生)。

My reference answer for this query technique has more explanation, a benchmark and links.

+0

嘿!非常感謝鏈接。它還包含有關如何添加適當索引的信息。 <3 <3 <3 –