2013-11-26 99 views
0

我試圖圍繞SQL包裝我的頭,我需要一些幫助搞清楚如何在PostgreSQL 9.3中執行以下查詢。查詢到ORDER BY從另一個SELECT返回的行數

我有一個用戶表,和朋友列出的用戶ID和多行朋友的用戶ID。

我想查詢一下用戶表和ORDER BY共同的朋友號碼到一個用戶ID。

因此,朋友表看起來像:

user_id | friend_user_id 
1  | 4 
1  | 5 
2  | 10 
3  | 7 

等等,讓用戶1只列出了4和5的朋友,和用戶2只列出了10個朋友,所以我想按friend_user_id中的用戶1的最高計數排序,以獲得user_id的結果。

+0

請張貼你的表模式和你想要的排序輸出種類的例子。 –

回答

2

Postgres的方式做到這一點:

SELECT * 
FORM users u 
LEFT JOIN (
    SELECT user_id, count(*) AS friends 
    FROM friends 
    ) f USING (user_id) 
ORDER BY f.friends DESC NULLS LAST, user_id -- as tiebreaker 
  • 關鍵字AS是表的別名只是噪音。但是不要從列別名中省略它。我引用手冊上"Omitting the AS Key Word"

    FROM項,無論是標準的和PostgreSQL允許AS到的別名是未保留的關鍵字之前被省略 。但是,由於句法歧義,因此對於輸出列名,這是不切實際的 。

    大膽重視我的。

  • ISNULL()是MySQL或SQL Server的自定義擴展。 Postgres使用SQL標準函數COALESCE()。但你不需要在這裏。改爲使用NULLS LAST clause,它更快更清潔。

  • 可以預計,多個用戶擁有相同數量的朋友。這些同伴將被任意排序。兩次調用相同的函數可能會產生不同的結果,這通常是不可取的。將更多表達式添加到ORDER BY。最終,主鍵可以解決任何剩餘的歧義。

  • 如果這兩個表共享相同的列名user_id(就像他們應該這樣做),則可以在連接子句中使用語法快捷鍵USING。另一個標準的SQL功能。非常受歡迎的副作用:user_id僅在SELECT *的輸出中列出一次,而不是在加入ON時。許多客戶端甚至不會在輸出中接受重複的列名稱。

+0

這很完美,謝謝! –

0

像這樣?

SELECT * FORM [users] u 
LEFT JOIN (SELECT user_id, COUNT(*) friends FROM fields) f 
ON u.user_id = f.user_id 
ORDER BY ISNULL(f.friends,0) DESC 
+0

除PostgreSQL中沒有'ISNULL'外,這是一個MySQL-ism。標準SQL使用'COALESCE'。 –