SQL Server 交叉应用不起作用?

标签 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

我试图学习交叉应用,因为它与内连接类似,但适用于函数。

在上面的查询中,我假设它应该只需要 dept=30,因为 order d.id desc 只会给出第一个 id,即 30,然后它应该返回 dept id = 30 的员工,但它给了我所有行以及所有部门。

查询出了什么问题,或者我错误地解释了交叉应用的概念。

最佳答案

你说“在上面的查询中,我假设它应该只需要 dept=30,因为 order d.id desc 只会给出第一个 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

APPLY 关键字意味着内部查询(逻辑上)针对外部查询的每一行调用一次。对于内部查询内部发生的情况,了解 SELECT 子句执行的逻辑顺序很有帮助。此顺序是:

  1. FROM 子句
  2. WHERE 子句
  3. 选择
  4. ORDER BY 子句
  5. TOP 运算符

请注意,在您的内部查询中,TOP 运算符将last 应用,远在 WHERE 子句之后。这意味着 where d.id = e.dept 将首先将内部行减少到 d.ide.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

此处,已使用另一个嵌套子查询对逻辑进行了重新排序,以确保先应用 ORDER BY,然后再应用 TOP 1WHERE 子句。 (请注意,这通常不是推荐的方法,因为嵌套子查询可能会妨碍可读性,我只是在这里使用它来保留 CROSS APPLY 并保留原始结构的其余部分)。

关于SQL Server 交叉应用不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20612958/

相关文章:

mysql - 何时/应该在 1 中存在两个实体 :1 Relationship become a Single Entity?

SQL Server 日数据类型?

sql - 任何使用Red Gate的SQL Source Control的人

sql - 在事务提交之前,在事务中进行的插入是否可以通过 SELECT 看到

sql - 复制具有不同 ID 的记录

java - JDBC 连接字符串与 selectMethod=cursor 断开连接

SQL 构建类型 2 维度

java - JPQL 比较运算符的占位符

mysql - 如何使用sql检查列表属性中的计数?

sql - 在 Postgresql 9.6.5 上使用 ltree 查询时出现语法错误