【问题标题】:SQL - Select from multiple tables with no results in one of themSQL - 从多个表中选择,其中一个没有结果
【发布时间】:2018-11-04 17:41:16
【问题描述】:

我认为这个问题之前可能已经回答过,但我找不到:我找到的所有结果都不是这个问题的解决方案......

假设我的数据库有以下表和关系(我无法更改它们):

  • 实体:用户、工作组和队列
  • 一个用户可以包含在多个工作组中,一个工作组可以有多个用户。
  • 一个工作组可以有多个队列,一个队列可以属于多个工作组。
  • 有两个表构成这些“多对多”关系:m2m_user_wg、m2m_wg_queue

我有一个这样的查询:

SELECT U.LOGIN, WG.WORKGROUP, Q.QUEUE
FROM USER U, M2M_USER_WG MUW, WORKGROUP W, M2M_WG_QUEUE MWQ, QUEUE Q
WHERE U.ID = MUW.WORKGROUP2USER
AND W.ID = MUW.USER2WORKGROUP
AND W.ID = MWQ.QUEUE2WORKGROUP
AND Q.ID = MWQ.WORKGROUP2QUEUE
AND U.LOGIN = 'johndoe'

当所有实体都有现有值时,此查询工作正常,但假设用户只有一个工作组,并且该工作组没有任何队列。工作组的 ID 不会存在于表 M2M_WG_QUEUE (MWQ) 中,因此查询不会显示结果。

我想要查看用户和他的工作组,即使其中一些没有队列。像这样的:

USER      WORKGROUP    QUEUE
johndoe   WG3          Q7
johndoe   WG3          Q8
johndoe   WG4          Q7
johndoe   WG9

在上面的例子中,结果应该是这样的:

USER      WORKGROUP    QUEUE
johndoe   WG6

我该怎么做?我认为它可能可以通过加入或 (+) 来完成,但我已经尝试了多种方式,但都没有奏效......

【问题讨论】:

  • 您正在使用内部联接(好吧,实际上是交叉联接,您的 WHERE 子句变成了内部联接,因为您使用的是我们在 1980 年代使用的过时的联接语法),您只得到匹配。您需要一个外连接,即使连接的表没有匹配项,您也可以在其中保留一行。在您的手册中查找连接(尤其是 INNER JOINLEFT OUTER JOIN)。顺便说一句:始终使用您正在使用的 DBMS(MySQL、Oracle、SQL Server 等)标记 SQL 问题。

标签: sql oracle select join many-to-many


【解决方案1】:

永远不要FROM 子句中使用逗号。 始终使用正确、明确、标准的JOIN 语法。亲

你的问题是你需要一个LEFT JOIN,大概是:

SELECT U.LOGIN, WG.WORKGROUP, Q.QUEUE
FROM USER U LEFT JOIN
     M2M_USER_WG MUW
     ON U.ID = MUW.WORKGROUP2USER LEFT JOIN
     WORKGROUP W
     ON W.ID = MUW.USER2WORKGROUP LEFT JOIN
     M2M_WG_QUEUE MWQ
     ON W.ID = MWQ.QUEUE2WORKGROUP LEFT JOIN
     QUEUE Q
     ON Q.ID = MWQ.WORKGROUP2QUEUE
WHERE U.LOGIN = 'johndoe';

【讨论】:

  • 谢谢,成功了!!但我很困惑,我一直使用你和@thorstenkettner 谈论的语法(from 子句中的逗号和 wheres 而不是连接),我学会了以这种方式进行查询,以及所有过程和 SQL 代码我在我正在工作的项目中看到的就是这样写的……这不是 1980 年代的项目。为什么在 from 中使用连接而不是逗号和 where 更好?
  • @JuanAntonioAuñónOchando 。 . .二十年后,是时候学习标准 SQL 语法了。因为甲骨文已经存在了很长时间,它有很多老程序员(在两种意义上)和很多很多有不良实践的代码。 (作为其中的一员,我觉得使用“旧”而不是侮辱很舒服。)
  • @Jalpesh 。 . .我完全按照我的意图编写代码。您在使用 SQL 和 Excel 进行数据分析的第 1 章中阅读了我的样式规则。
猜你喜欢
  • 2020-11-22
  • 2012-06-22
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多