【问题标题】:Query for joining all info from three tables查询加入三个表中的所有信息
【发布时间】:2011-12-13 15:24:47
【问题描述】:

我需要在 SQL Server 中加入 3 个表。这 3 个表基本上具有以下架构:

   Users                Items                     UsersItems
+--------+    +--------+-------------+    +--------+--------+-------+
| UserID |    | ItemID | Description |    | UserID | ItemId | Value |
+--------+    +--------+-------------+    +--------+--------+-------+
|   1    |    |   1    |    desc1    |    |   1    |    1   |   1   |
|   2    |    |   2    |    desc2    |    |   1    |    2   |   2   |
|  ...   |    |  ...   |    desc3    |    |   2    |    2   |   1   |
|   n    |    |   n    |    desc4    |    |   n    |    1   |   1   |
+--------+    +--------+-------------+    +--------+--------+-------+

如您所见,Users 和 Items 都可以无限增长,UsersItems 用于表达这两者之间的关系,还包括一个 Value 列。

我需要一个查询来检索所有用户,对于每个用户我需要所有项目及其对应的值。

如果UsersItems 中不存在该关系,则应为该行的Value 列返回 Null(或默认值)。

预期的查询结果应该是:

             ResultSet
    +--------+--------+-------+
    | UserID | ItemID | Value |
    +--------+--------+-------+
    |   1    |   1    |   1   |
    |   1    |   2    |   2   |
    |   1    |   n    |  NULL |
    |   2    |   1    |  NULL |
    |   2    |   2    |   1   |
    |   2    |   n    |  NULL |
    |   n    |   1    |   1   |
    |   n    |   n    |  NULL |
    +--------+--------+-------+

【问题讨论】:

  • 阅读 LEFT JOIN 并尝试一下。
  • 其实,也请阅读 CROSS JOIN。
  • 你要我们做你的功课吗?
  • @Neil 我对连接的维恩图有所了解,我只是不知道如何将其转换为查询,主要是因为我知道我需要的是(U 和 UI)和(I 和 UI ) 但由于这两个不会返回兼容的结果集,所以我不能在它们上调用 Union
  • @PMV 我会使用Homework 标签。我之所以问,是因为我需要对应用程序进行查询,但不知道该怎么做。

标签: sql sql-server-2005 join


【解决方案1】:

好的,由于有几个我认为不正确的答案,我将发布我认为的答案:

SELECT Users.UserID,
       Items.Description,
       UsersItems.Value
FROM
       Users
CROSS JOIN
       Items
LEFT JOIN
       UsersItems
ON
       Users.UserID = UsersItems.UserID
AND
       Items.ItemID = UsersItems.ItemID

我从您关于空值的评论中推断出您希望查看针对所有用户的所有项目,以及它所在的 UsersItems 表中的值。

【讨论】:

  • 那是我放弃时的查询,我只是缺少最后的AND 语句,因此我在Value 列中得到了不真实的值。比你!
【解决方案2】:
SELECT
     Users.UserID,
     Items.Description,
     Items.Value

FROM Users LEFT OUTER JOIN UsersItems
          ON Users.UserID = UsersItems.UserID
     LEFT OUTER JOIN Items
          ON UserItems.ItemID = Items.ItemID

【讨论】:

  • 这样不行,因为如果UsersItems中没有行,就不能加入Items。
  • 他说如果没有关系 null 很好,这就是为什么它是一个外连接
  • @paulbailey 如果没有连接,外部连接选择 NULL,如果表之间有连接,则选择信息。这正是你想要的。 Maess 是正确的。
  • 我认为这只是关于我当时如何阅读问题,因为他只为 value 列指定了 null。
【解决方案3】:

你这样做:

SELECT Users.UserID, Items.Description, Items.Value
FROM Users
LEFT OUTER JOIN UsersItems ON Users.UserID = UsersItems.UserID
LEFT OUTER JOIN Items ON UserItems.ItemID = Items.ItemID

有关左外连接的更多信息,请阅读以下内容:

表 A 的左外连接(或简称为左连接)的结果和 B 总是包含“左”表 (A) 的所有记录,即使 join-condition 在“右”表中没有找到任何匹配的记录 (乙)。这意味着如果 ON 子句匹配 B 中的 0(零)条记录, 连接仍然会在结果中返回一行——但每个都为 NULL 来自 B 的列。这意味着左外连接返回所有 左表中的值,加上右表中的匹配值 (如果没有匹配的连接谓词,则为 NULL)。如果正确的表 返回一行,左表返回多个匹配行 对于它,右表中的值将为每个重复 左表上的不同行。从 Oracle 9i 开始,LEFT OUTER JOIN 语句可以和 (+) 一样使用。

【讨论】:

    猜你喜欢
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多