2011-04-26 26 views
2

我在PostgreSQL數據庫中有三個表:用戶,活動,場所。如何使用外連接和笛卡爾積連接三個表

Users: 
- id 
- name 

Visits: 
- id 
- user_id 
- location_id 

Venues: 
- id 
- name 

我想如果用戶沒有訪問過一個地點尚未檢索所有活動爲特定用戶,事件。我已經試過了一些聯接:

SELECT venues.id as venue, COUNT(activities.id) as visits 
FROM users 
RIGHT OUTER JOIN activities ON users.id=activities.user_id 
RIGHT OUTER JOIN venues ON activities.venue_id=venues.id 
WHERE users.id=1234 
GROUP BY venues.id 
ORDER BY venues.id 

我想訪問變量包含0,在用戶沒有訪問過的位置(=有活動沒有條目),如果用戶的活動計數已經訪問過該位置。

但我只得到用戶訪問過的位置:

venue | visits 
    1  3 
    2  4 
    3  22 
    4  1 

我想,那RIGHT OUTER JOIN會從右側返回所有條目,但它沒有。

回答

8

LEFT OUTER JOIN意味着您需要左手錶中的所有實體,而不管JOIN條件(或謂詞)是否滿足。

但是,這也是笛卡兒產品(CROSS JOIN)實際上很有必要的罕見情況之一,因爲您想要查看每個用戶的每個場所。嘗試使用CROSS JOIN這樣的:

SELECT v.id as venue, COUNT(a.id) as visits 
FROM users AS u 
CROSS JOIN venues as v --<-- CROSS JOIN for Cartesian product between users and venues 
LEFT JOIN activities AS a ON u.id = a.user_id AND a.venue_id = v.id 
WHERE u.id = 1234 
GROUP BY v.id 
ORDER BY v.id 
+0

我試過了,但我得到了相同的輸出作爲正確的加入返回 – 23tux 2011-04-26 15:02:55

+0

thx爲您的編輯,但我得到一個錯誤,線附近'加入場館AS v '。不應該是'從用戶那裏,場所AS v'而不是'JOIN場館v'? – 23tux 2011-04-26 15:33:50

+0

hmmmm,'* ='不適用於PostgreSQL,有沒有其他辦法?你爲什麼要說老派符號? ;) – 23tux 2011-04-26 15:48:28

2

檢查了這一點:

http://db.apache.org/derby/docs/10.2/ref/rrefsqlj57522.html

基本加入explanations--他們可能會造成混淆。我想你可能想要在第一次連接中切換列,或者使用左外連接。

+1

「他們可能會造成混淆」 - 事實上,該文檔的作者,你掛使得口誤:「左外連接到B RIGHT OUTER JOIN A B等價,列的順序不同「 - 當然,他們的意思是,」......用**表格**以不同順序「。 – onedaywhen 2011-04-27 09:46:08

+0

好抓!我甚至沒有拿起它... – Ben 2011-04-28 16:35:59