【问题标题】:SQL issue with RIGHT JOINS右连接的 SQL 问题
【发布时间】:2019-09-24 17:42:20
【问题描述】:

以下 SQL 查询完全符合它应该做的事情,但我不知道如何更改它,所以它做我需要它做的事情。

SELECT 
    a.id AS comment_id, a.parent_comment_id, a.user_id, a.pid, a.comment, a.blocked_at, a.blocked_by, a.created_at, a.updated_at,
    b.name, b.is_moderator, COUNT(IF(d.type = 1, 1, NULL)) AS a_count, COUNT(IF(d.type = 2, 1, NULL)) AS b_count
FROM 
    comments AS a
RIGHT JOIN 
    users AS b ON b.id = a.user_id
RIGHT JOIN 
    node_user AS c ON c.user = b.id
RIGHT JOIN 
    nodes AS d ON d.id = c.node
WHERE 
    a.pid = 999
GROUP BY
    comment_id
ORDER BY
    a.created_at ASC

它获取属于特定 pid 的所有 cmets,然后是 RIGHT JOINS 附加用户数据,如 nameis_moderator,然后是 RIGHT JOINS 任何(所谓的)节点,包括基于 @987654328 的附加数据@ 和 node id。如SELECT 中所见,我根据节点类型对节点进行计数。

这对于在其帐户中附加了任何 nodes 的用户非常有用。但没有任何用户,因此node_usernodes 表中不存在id 的用户将不会显示在查询结果中。

所以我的问题:

我怎样才能做到这一点,即使没有任何nodes 的用户仍会显示在查询结果中,但带有0NULLa_countb_count

【问题讨论】:

  • 你不是在暗示一个内部连接,在 cmets 上有一个过滤器吗?
  • @CetinBasoz 可能,你能详细说明一下吗?
  • 虽然您使用的是右连接(如果您愿意,也可以使用左连接),但您在 cmets 上有一个过滤器,它可能因为(右或左)连接而为空。但是既然你明确说它应该是 999,那么你实际上是在说你的意思是内部连接。
  • 了解 LEFT/RIGHT JOIN ON 返回的内容:INNER JOIN ON 行 UNION ALL 由 NULL 扩展的不匹配的左/右表行。作为 OUTER JOIN 的一部分,始终知道您想要什么 INNER JOIN。 WHERE 或 INNER JOIN ON 在 LEFT/RIGHT JOIN ON 删除任何由 NULL 扩展的行后,需要右/左 [sic] 表列不为 NULL,即仅保留 INNER JOIN ON 行,即“将 OUTER JOIN 转换为 INNER加入”。你有那个。
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&运行代码;具有期望和实际输出(包括逐字错误消息)的示例输入(作为初始化代码);标签和版本;明确的规范和解释。这包括您可以提供的最少代码,即您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)对于包含 DBMS/产品和 DDL 的 SQL,其中包括约束和索引以及表格格式的基表初始化。

标签: sql select where-clause right-join


【解决方案1】:

我很确定你想要左连接而不是右连接。您还想修复表别名,使其有意义:

SELECT . . .
FROM comments c LEFT JOIN
     users u
     ON u.id = c.user_id LEFT JOIN
     node_user nu
     ON nu.user = u.id LEFT JOIN
     nodes n
     ON n.id = nu.node
WHERE c.pid = 999
GROUP BY c.id
ORDER BY c.created_at ASC;

这会将所有内容保留在 first 表中,而不管后续表中的行是否匹配。这似乎是你想要的。

【讨论】:

  • 这正是我所需要的,但似乎我在第一篇文章中忘记了一件事情:我还需要检查所有计数 a_countb_count 是否有 active = 1。但我想这是将COUNT(IF(d.type = 1, 1, NULL)) AS a_count 更改为COUNT(IF(d.type = 1 AND d.active = 1, 1, NULL)) AS a_count 的问题,对吧?
  • @luikstruik 。 . .像这样的东西应该做你想做的。
猜你喜欢
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
相关资源
最近更新 更多