我很难过,摸不着头脑。它一定很简单,但我没有看到它。
假设我有四张桌子:
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”子句不对应的“has”行数。例如,如果视频行只有一个视频ID为1的团队和一个完全不相关的标签,那么当它应该说“普通标签”时,它会给我“普通标签数量:1,普通团队数量:1” count:0(因为它是一个不相关的标签),常见的团队数:1“。
现在,只要我将查询限制为只有一个“has”表,就像这样:
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
然后它确实有效,但问题是当我尝试在查询中放入多个“has”表时。我尝试过使用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)
我也可以在Doctrine中使用它(我是愚蠢的,忘了WITH)。这是最佳方式吗?
答案 0 :(得分: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 |
+------+-----------------+------------------+------------------+
答案 1 :(得分: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
真正的解决方案是分别聚合每个值,然后将结果连接在一起。