bms*_*dev 4 t-sql sql-server join sql-server-2012 outer-apply
我通过文章去约CROSS APPLY,并OUTER APPLY在SQL Server中.以下表格用于说明两者.
员工表:
EmployeeID FirstName LastName DepartmentID
1 Orlando Gee 1
2 Keith Harris 2
3 Donna Carreras 3
4 Janet Gates 3
Run Code Online (Sandbox Code Playgroud)
部门表:
DepartmentID Name
1 Engineering
2 Administration
3 Sales
4 Marketing
5 Finance
Run Code Online (Sandbox Code Playgroud)
我明白这OUTER APPLY是类似于LEFT OUTER JOIN.但当我OUTER APPLY在表之间应用如下,
select * from Department e
outer apply
Employee d
where d.DepartmentID = e.DepartmentID
Run Code Online (Sandbox Code Playgroud)
我得到了以下结果(与INNER JOIN结果相同)
DepartmentID Name EmployeeID FirstName LastName DepartmentID
1 Engineering 1 Orlando Gee 1
2 Administration 2 Keith Harris 2
3 Sales 3 Donna Carreras 3
3 Sales 4 Janet Gates 3
Run Code Online (Sandbox Code Playgroud)
当我OUTER APPLY 在表之间应用如下(right table作为子查询).
select * from Department e
outer apply
(
select * from
Employee d
where d.DepartmentID = e.DepartmentID
)a
Run Code Online (Sandbox Code Playgroud)
我得到了以下结果(与LEFT OUTER JOIN结果相同)
DepartmentID Name EmployeeID FirstName LastName DepartmentID
1 Engineering 1 Orlando Gee 1
2 Administration 2 Keith Harris 2
3 Sales 3 Donna Carreras 3
3 Sales 4 Janet Gates 3
4 Marketing NULL NULL NULL NULL
5 Finance NULL NULL NULL NULL
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么这两个查询有所不同outputs吗?
我认为理解这一点的关键是看到这个查询的输出:
select * from Department e
outer apply
Employee d
--where d.DepartmentID = e.DepartmentID
Run Code Online (Sandbox Code Playgroud)
这只是简单地给你两个表的笛卡尔积:
DepartmentID Name EmployeeID FirstName LastName DepartmentID
--------------------------------------------------------------------------------------
1 Engineering 1 Orlando Gee 1
2 Administration 1 Orlando Gee 1
3 Sales 1 Orlando Gee 1
4 Marketing 1 Orlando Gee 1
5 Finance 1 Orlando Gee 1
1 Engineering 2 Keith Harris 2
2 Administration 2 Keith Harris 2
3 Sales 2 Keith Harris 2
4 Marketing 2 Keith Harris 2
5 Finance 2 Keith Harris 2
1 Engineering 3 Donna Carreras 3
2 Administration 3 Donna Carreras 3
3 Sales 3 Donna Carreras 3
4 Marketing 3 Donna Carreras 3
5 Finance 3 Donna Carreras 3
1 Engineering 4 Janet Gates 3
2 Administration 4 Janet Gates 3
3 Sales 4 Janet Gates 3
4 Marketing 4 Janet Gates 3
5 Finance 4 Janet Gates 3
Run Code Online (Sandbox Code Playgroud)
现在,当您在where子句中添加回来时,您将where d.DepartmentID = e.DepartmentID消除大部分这些行:
DepartmentID Name EmployeeID FirstName LastName DepartmentID
--------------------------------------------------------------------------------------
1 Engineering 1 Orlando Gee 1
2 Administration 2 Keith Harris 2
3 Sales 3 Donna Carreras 3
3 Sales 4 Janet Gates 3
Run Code Online (Sandbox Code Playgroud)
此查询在语义上等效于:
SELECT * FROM Department e
CROSS JOIN Employee d
WHERE d.DepartmentID = e.DepartmentID;
Run Code Online (Sandbox Code Playgroud)
这与以下内容相同:
SELECT * FROM Department e
INNER JOIN Employee d
ON d.DepartmentID = e.DepartmentID;
Run Code Online (Sandbox Code Playgroud)
因此,即使你有一个OUTER APPLYwhere子句将其转换成一个INNER JOIN,从而删除没有员工的部门.