MySQL JOIN 与 NULL 值
我正在尝试执行一个相当复杂的(至少对我来说)查询,其中涉及获取可能具有 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
值我也渴望。
有什么想法要做什么吗?
I'm trying to do a rather complex (for me, at least) query that involves fetching rows that may have NULL
values.
There are four tables here, tags
, questions_tags
, users_experience
, and answers
. The connections are rather straightforward. Questions are tagged, tags have names, users give answers to questions, and users have experience with particular tags. I want to find answers that users have given, and their experience (which may be NULL
) for that questions' tags. I'm ordering by the number of answers given for a particular tag.
My query is as follows. This is not at all optimized (and if you have optimization suggestions, please suggest away!):
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;
The problem I'm facing with the above query is that if anyone has noted experience for a particular tag, that will show up for the user whether it is their experience or not. I'd like to see only that particular user's experience, which this query is just not doing. I've run into this problem elsewhere and been stumped, so have had to hack around it.
I tried adding AND ue.uid = 1
to the query, but that will limit the results on only those where the experience has already been given, and not return the NULL
values I desire, as well.
Any thoughts on what to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的
AND ue.uid = 1
直觉并没有错,但它属于ON
子句,因此它是JOIN
的一部分,而且它是用于确定哪些行有资格加入。(然后该连接应放置在
answers
连接下。)Your
AND ue.uid = 1
instinct wasn't wrong, but it belongs in theON
clause so it's part of theJOIN
, and it's used to determine which rows are eligible to join.(And that join should then be placed under the
answers
join.)我认为您需要包括用户的表。按用户表中的 uid 进行过滤(保证是这样),这应该会给你你想要的东西。 (包括空值)。我不知道您的用户表到底是什么样子,但我假设您的查询是这样的:
至于优化 -
LEFT JOIN
通常被认为是不好的,除非这些表非常小。 MySQL 基本上必须在整个表中搜索 NULL 值。实际上,首先检查用户在左连接表中是否有任何记录可能会更快,并且只有在找到记录时才使用常规JOIN
发出第二个查询。希望有帮助!
I think you need to include a user's table. Filter by the uid in the user's table (where it's guaranteed to be) and that should give you what you want. (including the null values). I don't know exactly what your user table looks like but I'm assuming your query would be something like this:
As for optimization -
LEFT JOIN
is usually considered bad unless these tables are pretty small. MySQL basically has to search the whole table forNULL
values. It might actually be faster to check if your user has any records in the left joined tables first and only issue a second query using regularJOIN
only if you find records.Hope that helps!