【发布时间】:2011-01-31 20:40:22
【问题描述】:
我已经在 StackOverflow 和 Google 上搜索过这个问题的答案。
我正在尝试创建一个 Microsot SQL Server 2008 视图。不是存储过程。不是函数。只是一个查询(即一个视图)。
我有三张桌子。第一个表定义了一个公共键,比如“CompanyID”。另外两个表有一个有时很常见的字段,比如“EmployeeName”。
我想要一个单表结果,当我的 WHERE 子句显示“WHERE CompanyID = 12”时,该结果如下所示:
CompanyID | TableA | TableB
12 | John Doe | John Doe
12 | Betty Sue | NULL
12 | NULL | Billy Bob
我尝试了如下所示的 FULL OUTER JOIN:
SELECT Company.CompanyID,
TableA.EmployeeName,
TableB.EmployeeName
FROM Company
FULL OUTER JOIN TableA ON Company.CompanyID = TableA.CompanyID
FULL OUTER JOIN TableB ON
Company.CompanyID = TableB.CompanyID AND
(TableA.EmployeeName IS NULL OR TableB.EmployeeName IS NULL OR TableB.EmployeeName = TableA.EmployeeName)
我只从一个匹配的表中得到 NULL,我没有得到另一个表的扩展。在上面的示例中,我基本上只得到了第一行和第三行,而不是第二行。
有人可以帮我创建这个查询并告诉我这是如何正确完成的吗?
顺便说一句,我已经有一个看起来非常干净并填充内存表的存储过程,但这不是我想要的。
谢谢。
-- 编辑:
以下是当前不起作用的完整示例(缺少“someone 2”和“someone 3”。
DECLARE @Company TABLE
(
CompanyID int
)
INSERT INTO @Company (CompanyID) VALUES (10)
INSERT INTO @Company (CompanyID) VALUES (12)
DECLARE @TableA TABLE
(
EmployeeId int,
CompanyId int,
EmployeeName varchar(30)
)
DECLARE @TableB TABLE
(
EmployeeId int,
CompanyId int,
EmployeeName varchar(30)
)
INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 1, 10, 'someone' )
--INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )
--VALUES ( 2, 12, 'someone 2' )
INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 3, 12, 'someone 3' )
INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 3, 12, 'someone 4' )
INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 1, 10, 'someone' )
INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 2, 12, 'someone 2' )
--INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )
--VALUES ( 3, 12, 'someone 3' )
INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 3, 12, 'someone 4' )
SELECT Company.CompanyID,
TableA.EmployeeName,
TableB.EmployeeName
FROM @Company Company
FULL OUTER JOIN @TableA TableA ON Company.CompanyID = TableA.CompanyID
FULL OUTER JOIN @TableB TableB ON Company.CompanyID = TableB.CompanyID
WHERE
(
TableA.EmployeeName IS NULL OR TableB.EmployeeName IS NULL OR
TableB.EmployeeName = TableA.EmployeeName
)
AND Company.CompanyID = 12
结果:
CompanyID EmployeeName EmployeeName
12 someone 4 someone 4
我想要什么:
CompanyID EmployeeName EmployeeName
12 NULL someone 2
12 someone 3 NULL
12 someone 4 someone 4
【问题讨论】:
-
您实际上不需要查询
Company表来满足您的输出要求。尝试在两个表之间进行完全外连接。 -
@ar:我需要选择 CompanyID 并对其进行过滤。
-
对于给定的数据,正确的结果应该是什么?你能包括那个吗
-
您不能按照 ar 的建议进行操作(只需对表 A 和表 B 进行完全外部联接)并仅在 TableA.CompanyID 而不是 Company.CompanyID 上选择和过滤吗?或者您还需要从公司表中选择其他字段吗?
-
我实际使用的两张表的性能其实真的很慢。它是 SQLXML 节点值的子选择。在加入之前从两个表中进行选择时,我绝对必须对 ID(在示例中为 CompanyID)进行预过滤。我知道如何使用存储过程中的临时表执行此操作,但要使其在可重用查询或视图中工作,我想看看这是否可能在整个查询底部的外部过滤器包括的 SELECT 中对 ID 的唯一引用,在示例中是 WHERE Company.CompanyID = 12。
标签: sql join outer-join full-outer-join