Reg*_*ser 5 sql sql-server sql-server-2008 cross-apply
http://sqlfiddle.com/#!3/78273/1
create table emptb1
(
id int,
name varchar(20),
dept int
)
insert into emptb1 values (1,'vish',10);
insert into emptb1 values (2,'vish',10);
insert into emptb1 values (3,'vish',30);
insert into emptb1 values (4,'vish',20);
create table depttb1
(
id int,
name varchar(20)
)
insert into depttb1 values(10,'IT')
insert into depttb1 values(20,'AC')
insert into depttb1 values(30,'LIC')
select * from emptb1
select e.id, e.name, a.id
from emptb1 e
cross apply
(
select top 1 * from depttb1 d
where d.id = e.dept
order by d.id desc
) a
Run Code Online (Sandbox Code Playgroud)
我试图学习交叉应用,因为它类似于内连接,但与函数一起工作.
在上面的查询我假设它应该只采取dept = 30因为订单d.id desc将只给出top的第一个id为30然后它应该返回dept id = 30的员工但是它给了我所有的行和所有的DEPTID.
查询有什么问题,或者我错误地解释了交叉申请的概念.
你说" 在上面的查询我假设它应该只采取dept = 30因为订单d.id desc将只给出top的第一个id为30然后它应该返回dept id = 30的员工 ".
这不是它的工作原理.这是您的查询(为了清晰起见,重新格式化了一点):
select e.id, e.name, a.id
from emptb1 e
cross apply
(
select top 1 *
from depttb1 d
where d.id = e.dept
order by d.id desc
) a
Run Code Online (Sandbox Code Playgroud)
该APPLY关键字是指内部查询是(逻辑上)的外部查询的每一行调用一次.对于内部查询中发生的事情,理解SELECT执行a的子句的逻辑顺序是有帮助的.这个顺序是:
FROM 条款WHERE 条款SELECT 列ORDER BY 条款TOP 操作者请注意,在您的内部查询中,TOP操作符最后应用于该WHERE子句之后.这意味着where d.id = e.dept将首先将内部行减少到d.id与e.dept外部行匹配的行(不一定是30行),然后对它们进行排序,然后返回第一行.它为外部查询中的每一行执行此操作.很明显,他们中的许多人都不会30.
你想要的将更像是这样(仍然保留CROSS APPLY):
select e.id, e.name, a.id
from emptb1 e
cross apply
(
select top 1 *
from
(
select top 1 *
from depttb1 d
order by d.id desc
) b
where b.id = e.dept
) a
Run Code Online (Sandbox Code Playgroud)
在这里,逻辑已被使用另一个嵌套子查询确保了的重新排序ORDER BY,然后TOP 1得到应用之前的WHERE条款.(请注意,这通常不建议这样做,因为嵌套的子查询可能会妨碍可读性,我只是在这里使用它来保留CROSS APPLY并保留原始结构的其余部分).
| 归档时间: |
|
| 查看次数: |
4142 次 |
| 最近记录: |