2016-10-26 49 views
7

我有三個表格:歷史記錄,視頻和用戶。 以下兩個查詢顯示每個視頻的意見法國用戶或德國用戶數:將兩個select查詢合併爲一個

SELECT V.idVideo, COUNT(H.idVideo) AS nb_fr 
FROM HISTORY H 
INNER JOIN VIDEO V ON V.idVideo = H.idVideo 
INNER JOIN USER U ON U.idUser = H.idUser 
WHERE U.nationality = 'french' 
GROUP BY H.idVideo 
ORDER BY V.idVideo; 

SELECT V.idVideo, COUNT(H.idVideo) AS nb_ge 
FROM HISTORY H 
INNER JOIN VIDEO V ON V.idVideo = H.idVideo 
INNER JOIN USER U ON U.idUser = H.idUser 
WHERE U.nationality = 'german' 
GROUP BY H.idVideo 
ORDER BY V.idVideo 

但如何結合這兩個查詢只生一個? 我想這樣的事情:

idVideo | nb_fr | nb_ge 
----------------------- 
    1 | 5 | 4 
    2 | 3 | 6 
    3 | 2 | 8 
    4 | 3 | 3 

回答

9

使用case表達式來完成有條件聚集:

SELECT V.idVideo, 
     COUNT(case when U.nationality = 'french' then H.idVideo end) AS nb_fr, 
     COUNT(case when U.nationality = 'german' then H.idVideo end) AS nb_ge 
FROM HISTORY H 
INNER JOIN VIDEO V ON V.idVideo = H.idVideo 
INNER JOIN USER U ON U.idUser = H.idUser 
WHERE U.nationality in ('french', 'german') 
GROUP BY V.idVideo 
ORDER BY V.idVideo; 

注意改變GROUP BY V.idVideo,怎麼一回事,因爲這是所選列。

5

可以使用條件與聚集做CASE EXPRESSION它:

SELECT V.idVideo, 
     COUNT(CASE WHEN U.nationality = 'french' THEN 1 END) AS nb_fr, 
     COUNT(CASE WHEN U.nationality = 'german' THEN 1 END) AS nb_ge 
FROM HISTORY H 
INNER JOIN VIDEO V ON V.idVideo = H.idVideo 
INNER JOIN USER U ON U.idUser = H.idUser 
GROUP BY H.idVideo 
ORDER BY V.idVideo 
4

使用條件彙總:

SELECT H.idVideo, 
     SUM(CASE WHEN U.nationality = 'french' THEN 1 ELSE 0 END) as nb_fr, 
     SUM(CASE WHEN U.nationality = 'german' THEN 1 ELSE 0 END) as nb_ge 
FROM HISTORY H INNER JOIN 
    USER U 
    ON U.idUser = H.idUser 
GROUP BY H.idVideo 
ORDER BY H.idVideo; 

另外請注意,查詢可以簡化。可能不需要JOINVIDEO(假設idVideo是唯一的,這是一個非常合理的假設)。

此外,ORDER BYGROUP BY應使用相同的列引用。

+3

這不應該被公佈。你沒有看到其他兩個答案嗎? –

+2

其實第二眼看到他戈登避開了從視頻中選擇這似乎是不必要的,所以他的回答很好:) @TimBiegeleisen – sagi

+0

@sagi好吧,然後我部分撤回我的上述評論。爲了記錄,我昨天兩次提高了Gordon :-) –

2

從Oracle 11.1開始,您可以使用PIVOT操作:

select idvideo, nb_fr, nb_ge 
from (select h.idvideo, u.nationality 
     from history h inner join user u on h.iduser = u.iduser 
     ) 
pivot (count(*) for nationality in ('french' as nb_fr, 'german' as nb_ge)) 
order by idvideo 
;