我正在尝试执行一个相当复杂的查询(至少对我来说),该查询涉及获取可能具有NULL
值的行。
这里有四个表,tags
、questions_tags
、users_experience
和answers
。它们之间的联系相当直接。问题被标记,标签有名字,用户给出问题的答案,用户有特定标签的经验。我想找到用户给出的答案,以及他们对这些问题标签的体验(可能是NULL
)。我是根据特定标签的答案数排序的。
我的查询如下。这根本不是优化的(如果您有优化建议,请建议!):
SELECT t.tag_id, t.name, ue.body, COUNT(a.qid)
FROM tags AS t
LEFT JOIN users_experience AS ue
ON t.tag_id = ue.tag_id
LEFT JOIN questions_tags AS qt
ON qt.tag_id = t.tag_id
LEFT JOIN answers AS a
ON a.qid = qt.qid
WHERE a.uid=1
GROUP BY t.tag_id
ORDER BY COUNT(a.qid) DESC;
我在上面的查询中遇到的问题是,如果任何人注意到某个特定标记的体验,那么不管它是否是他们的体验,它都会显示给用户。我只想看到特定用户的体验,而这个查询并没有这样做。我在别的地方遇到了这个问题,因此不得不绕开它。
我尝试将AND ue.uid = 1
添加到查询中,但这只会限制已经给出体验的结果,而不会返回我想要的NULL
值。
对该怎么办有什么想法吗?
发布于 2010-11-17 22:36:12
您的AND ue.uid = 1
本能没有错,但它属于ON
子句,因此它是JOIN
的一部分,用于确定哪些行有资格加入。
LEFT JOIN users_experience AS ue
ON t.tag_id = ue.tag_id AND ue.uid = a.uid
(然后,应该将该联接放在answers
联接下。)
发布于 2010-11-17 22:35:32
我认为你需要包括一个用户的桌子。通过用户表中的uid进行过滤(在那里它保证在那里),这应该会给你想要的东西。(包括空值)。我不知道您的用户表到底是什么样子,但我假设您的查询如下所示:
SELECT t.tag_id, t.name, ue.body, COUNT(a.qid)
FROM users
LEFT JOIN users_experience AS ue
ON users.uid = ue.uid
LEFT JOIN tags
ON t.tag_id = ue.tag_id
LEFT JOIN questions_tags AS qt
ON qt.tag_id = t.tag_id
LEFT JOIN answers AS a
ON a.qid = qt.qid
WHERE users.uid=1
GROUP BY t.tag_id
ORDER BY COUNT(a.qid) DESC;
至于优化- LEFT JOIN
通常被认为是不好的,除非这些表非常小。MySQL基本上必须搜索整个表中的NULL
值。实际上,首先检查您的用户是否在左侧联接表中有任何记录可能更快,并且只有在找到记录时才使用常规JOIN
发出第二个查询。
希望这能帮上忙!
https://stackoverflow.com/questions/4209763
复制相似问题