2017-03-31 31 views
0

我努力解決以下問題: 我有兩個表在我的數據庫中: 視頻和users_videos作爲視頻和用戶之間的樞紐(我從令牌接收user_id,所以用戶表是在另一個數據庫)與「擁有」列選擇多對多關係

有一個用戶ID,我想選擇所有視頻,並附上包含true或false的列是否擁有一個視頻。

到目前爲止,我意識到這與下面的查詢:

SELECT v.*, TRUE AS has_video FROM users_videos AS uv 
RIGHT JOIN videos AS v 
ON uv.video_id = v.id 
WHERE (uv.user_id = 1) 
UNION 
(
    SELECT v.*, FALSE AS has_video FROM videos AS v 

    EXCEPT 

    SELECT v.*, FALSE AS has_video FROM users_videos AS uv 
    RIGHT JOIN videos AS v 
    ON uv.video_id = v.id 
    WHERE (uv.user_id = 1) 
) 

雖然它選擇的所有視頻的3倍。有沒有更好的解決這類問題的方法?

@EDIT ---

表結構

users_videos: 
id integer 
user_id integer 
video_id integer 

videos: 
id: integer 
title: string 

實施例的數據:

users_videos

| id | user_id | video_id 
------------------------- 
    1 1   1 

視頻

| id | title | 
---------------- 
    1 | Example 1 
----------------- 
    2 | Example 2 
----------------- 

期望的結果:

| id | title  | has_video 
------------------------------ 
    1 | Example 1 | true 
------------------------------ 
    2 | Example 2 | false 
------------------------------ 

@UPDATE -

使用@Stefano賈尼尼方法:

SELECT DISTINCT 
     v.*, 
     CASE 
      WHEN uv.user_id IS NULL OR uv.user_id <> 1 THEN FALSE 
      ELSE TRUE 
     END has_video 
FROM videos v 
LEFT JOIN 
     users_videos uv 
ON  uv.video_id = v.id 

但一個問題來到我的腦海:

如果我想要顯示特定類別的視頻? 比方說,這是另一種多對多的關係上

視頻和類別表與樞videos_categories

+0

添加一些示例表格數據和預期結果 - 所有以及格式化文本。 – jarlh

+3

這些右連接以普通內連接的方式執行... – jarlh

+0

已更新爲示例數據和結構 –

回答

1

你可以做,如果沒有UNIONEXCEPT這樣

select distinct 
     v.*, 
     case 
      when uv.user_id is null or uv.user_id <> 1 then false 
      else true 
     end has_video 
from videos v 
left join 
     user_videos uv 
on  uv.video_id = v.id 

既然你形容這是一個many-to-many關係,多個用戶可以擁有相同的視頻,因此需要distinct

rightleft連接的交換隻是因爲我認爲它更易於閱讀。

編輯

要過濾特定類別的結果(如每題編輯),你可以在where

select distinct 
     v.*, 
     case 
      when uv.user_id is null or uv.user_id <> 1 then false 
      else true 
     end has_video 
from videos v 
join videos_categories vc 
on  v.id = vc.video_id 
join categories c 
on  vc.category_id = c.id 
left join 
     user_videos uv 
on  uv.video_id = v.id 
where c.category = 'someCategory' 
+0

很好的答案,完美的作品^^ –

+0

相反,從右到左加入... – jarlh

+0

我修好了,謝謝:) –

-1

您想選擇所有添加幾個join和條件視頻和說每個視頻是否用戶1擁有它。因此,從視頻中選擇並查找用戶的視頻:

select 
    v.*, 
    id in (select video_id from users_videos where user_id = 1) as has_video 
from videos v;