2012-08-15 68 views
2

我很難過,抓撓我的頭。它一定很簡單,但我沒有看到它。分組,計數和在哪裏

比方說,我有四個表:

video = id 
hastag = id, tag_id, video_id 
hasteam = id, team_id, video_id 
hasidol = id, idol_id, video_id 

此數據集(只是爲例):

video = (1), (2), (3) 
hastag = (1, 1, 1), (2, 1, 2), (3, 2, 3) 
hasteam = (1, 1, 1), (2, 1, 3), (3, 2, 2) 
hasidol = (1, 1, 3) 

而這個查詢:

SELECT v.id , 
COUNT(vhtag.id), 
COUNT(vhteam.id), 
COUNT(vhidol.id) 
FROM video v 
LEFT JOIN hastag vhtag ON vhtag.video_id = v.id 
LEFT JOIN hasteam vhteam ON vhteam.video_id = v.id 
LEFT JOIN hasidol vhidol ON vhidol.video_id = v.id 

WHERE 
v.id <> 1 
AND 
(
    vhtag.tag_id IN (SELECT htt2.tag_id FROM hastag htt2 WHERE video_id = 1) 
    OR 
    vhteam.team_id IN (SELECT htt3.team_id FROM hasteam htt3 WHERE video_id = 1) 
    OR 
    vhidol.idol_id IN (SELECT htt4.idol_id FROM hasidol htt4 WHERE video_id = 1) 
) 
GROUP BY v.id 

它給我的罪名「有」行不符合WHERE子句。例如,如果視頻行只有一個視頻標識爲1的單個團隊和一個完全不相關的標籤,那麼當它應該顯示「公共標籤時,它會給我」常用標籤數:1,常用團隊數:1「計數:0(因爲它是一個不相關的標籤),常用團隊數:1「。

現在,只要我限制查詢到只有一個「有」表,像這樣:

SELECT v.id , 
COUNT(vhtag.id) 
FROM video v 
LEFT JOIN hastag vhtag ON vhtag.video_id = v.id 

WHERE 
v.id <> 1 
AND 
(
    vhtag.tag_id IN (SELECT htt2.tag_id FROM hastag htt2 WHERE video_id = 1) 
) 
GROUP BY v.id 

然後它的工作,但問題是,當我試圖把一個以上的「有「表進入查詢。我嘗試過使用HAVING,但它不能識別「vhtag.tag_id」列。 我很明顯在這裏做錯了什麼,任何人都可以幫助我?

編輯:

這種作品:

LEFT JOIN hastag vhtag ON vhtag.video_id = v.id AND vhtag.tag_id IN (SELECT htt2.tag_id FROM hastag htt2 WHERE video_id = 1) 
LEFT JOIN hasteam vhteam ON vhteam.video_id = v.id AND vhteam.team_id IN (SELECT htt3.team_id FROM hasteam htt3 WHERE video_id = 1) 
LEFT JOIN hasidol vhidol ON vhidol.video_id = v.id AND vhidol.idol_id IN (SELECT htt4.idol_id FROM hasidol htt4 WHERE video_id = 1) 

我可以使用,在學說太(我是啞巴,忘了關於使用)。這是最佳的方式嗎?

+0

請說出查詢的預期結果或示例數據中指定的結果。 – pkmiec 2012-08-15 14:54:36

+0

對不起,發佈後已經編輯了幾次問題。現在應該更清楚了。 – user1600837 2012-08-15 15:22:43

+0

請提供所需的結果集。它可能有幫助。 – Devart 2012-08-16 05:06:03

回答

0

儘量簡化查詢,例如以這種方式 -

SELECT 
    v.id, 
    COUNT(vhtag.id), 
    COUNT(vhteam.id), 
    COUNT(vhidol.id) 
FROM 
    video v 
LEFT JOIN (SELECT * FROM hastag WHERE video_id = 1) vhtag 
    ON vhtag.video_id = v.id 
LEFT JOIN (SELECT * FROM hasteam WHERE video_id = 1) vhteam 
    ON vhteam.video_id = v.id 
LEFT JOIN (SELECT * FROM hasidol WHERE video_id = 1) vhidol 
    ON vhidol.video_id = v.id 
WHERE 
    v.id <> 1 
GROUP BY 
    v.id 

它是否給正確的結果?

輸出:

+------+-----------------+------------------+------------------+ 
| id | COUNT(vhtag.id) | COUNT(vhteam.id) | COUNT(vhidol.id) | 
+------+-----------------+------------------+------------------+ 
| 2 |    0 |    0 |    0 | 
| 3 |    0 |    0 |    0 | 
+------+-----------------+------------------+------------------+ 
+0

不幸的是,這不會返回任何行,而我在我的編輯中發佈的連接確實有效。如果我想冒險一個猜測,也許是因爲你的連接基本上重疊了兩個條件:video_id = 1和video_id = v.id,這在這種情況下是矛盾的。 – user1600837 2012-08-15 15:47:08

0

您有您的聯接是使每個團隊內部的交叉連接的問題。

最簡單的方法是做計數不同:

SELECT v.id , COUNT(distinct vhtag.id), COUNT(distinct vhteam.id), 
     COUNT(distinct vhidol.id) 
FROM video v LEFT JOIN 
    hastag vhtag 
    ON vhtag.video_id = v.id 
    LEFT JOIN hasteam vhteam 
    ON vhteam.video_id = v.id 
    LEFT JOIN hasidol vhidol 
    ON vhidol.video_id = v.id 

真正的解決方案是聚合的每個值分別,然後將結果結合在一起。

+0

這並不是正在發生的事情。對不起,我知道我可能不是最好的解釋,但請注意,我的查詢中有一個「1」,這是一個作爲參數傳遞的視頻ID。這不僅僅是加入v.id.查看我編輯中的連接以查看我的意思。基本上,它使得關聯 - 查找共享標籤的視頻(至少共享一個「擁有」,也就是說,他們至少有一個共同的三種標籤類型之一的實例)與我正在使用的ID相同的視頻作爲參數(在這種情況下,1)。 – user1600837 2012-08-15 20:13:23