我需要在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 |
+--------+--------+-------+
答案 0 :(得分:2)
好的,既然我认为有几个答案是不正确的,我会发布我认为答案的答案:
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表的Value。
答案 1 :(得分:1)
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
答案 2 :(得分:0)
你这样做:
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在“右”表中找不到任何匹配的记录 (B)。这意味着如果ON子句匹配B中的0(零)记录, 连接仍会在结果中返回一行 - 但每个中都有NULL 来自B的列。这意味着左外连接返回所有 左表中的值加上右表中的匹配值 (如果没有匹配的连接谓词,则为NULL)。如果是正确的表 返回一行,左表返回多个匹配的行 对于它,右表中的值将重复 左表上的不同行。从Oracle 9i开始,LEFT OUTER 可以使用JOIN语句以及(+)。