MySQL JOIN 与 NULL 值

发布于 2024-10-03 05:20:46 字数 876 浏览 1 评论 0原文

我正在尝试执行一个相当复杂的(至少对我来说)查询,其中涉及获取可能具有 NULL 值的行。

这里有四个表:tagsquestions_tagsusers_experienceanswers。连接相当简单。问题被标记,标签有名称,用户给出问题的答案,并且用户对特定标签有经验。我想找到用户给出的答案,以及他们对这些问题标签的体验(可能是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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谈场末日恋爱 2024-10-10 05:20:46

您的 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 连接下。)

Your AND ue.uid = 1 instinct wasn't wrong, but it belongs in the ON clause so it's part of the JOIN, and it's used to determine which rows are eligible to join.

LEFT JOIN users_experience AS ue
  ON t.tag_id = ue.tag_id AND ue.uid = a.uid

(And that join should then be placed under the answers join.)

北音执念 2024-10-10 05:20:46

我认为您需要包括用户的表。按用户表中的 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 发出第二个查询。

希望有帮助!

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:

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;

As for optimization - LEFT JOIN is usually considered bad unless these tables are pretty small. MySQL basically has to search the whole table for NULL 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 regular JOIN only if you find records.

Hope that helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文