2015-04-25 62 views
1

這可能聽起來很麻煩,所以請耐心等待。 :)Postgres查詢根據行數和存在進行選擇

我有兩個表:usersprofiles。用戶可以擁有多個配置文件,當用戶將OAuth導入Facebook或Google之類的提供商時會填寫這些配置文件。 profiles有一列名稱爲'Google'或'Facebook'的source,並且該列中的個人資料的公開image_url

如果用戶有關聯的配置文件,當我在網頁的列表中顯示用戶時,我想在img標記中使用image_url。如果用戶有多個配置文件,我希望Facebook上的圖片優先於Google。

因此,對於所有用戶,我想獲得適當的image_url以及其他user.*屬性。我可以在一個Postgres查詢中完全做到這一點嗎?如果是這樣,它會是什麼樣子?

到目前爲止(尷尬),我的一切是這樣的:

select image_url from users join profiles on users.id = profiles.user_id; 

這會給我多行如果用戶連接多個配置文件。我想修改該查詢,以便:

  • 沒有相關配置文件的用戶應該有nullimage_url
  • 誰的用戶只具有關聯的谷歌個人資料應具備的圖像URL從,谷歌個人資料
  • 誰的用戶只具有關聯的Facebook檔案應具備的圖像URL從Facebook的個人主頁
  • 誰的用戶同時擁有相關的Facebook的個人資料和谷歌個人資料應該有Facebook的圖片URL

任何SQL專家都可以權衡嗎?謝謝!

澄清:

  • 配置文件只能從Facebook或谷歌。用戶只能擁有1個Facebook個人資料和/或1個Google個人資料。 (也就是說,用戶不能擁有多個谷歌個人資料他也不能有多個Facebook個人主頁。)
+0

用戶可以擁有多個不包含Facebook或Google的個人資料嗎? –

+0

@vivek,您的查詢不會返回Google image_url。我會寫一個澄清 – user5243421

+0

我不認爲這是必要的。所有相關的專欄都在問題中提到,包括這些表格如何相互關聯......您認爲缺少什麼? – user5243421

回答

1

優雅的解決方案將使用兩個CTE的和COALESCE

WITH fb AS (
    SELECT user_id, image_url 
    FROM profiles 
    WHERE profile = 'Facebook' 
), ggl AS (
    SELECT user_id, image_url 
    FROM profiles 
    WHERE profile = 'Google' 
) 
SELECT users.*, COALESCE(fb.image_url, ggl.image_url) 
FROM users 
LEFT JOIN ggl ON ggl.user_id = users.id 
LEFT JOIN fb ON fb.user_id = users.id 

第一CTE得到了Facebook image_url,如果可用的話,第二個CTE獲取Google image_url。 COALESCE確保Facebook image_url被選中(如果存在)。

+0

哦,有趣。我一直在試圖查看「CASE」關鍵字。我不知道'COALESCE'。 – user5243421

+0

這很有趣,因爲它是文檔中的相同頁面!只要繼續閱讀。 – Patrick

+0

我想我只是看着StackOverflow的答案和關於'CASE'的教程哈哈 – user5243421