5

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

内部結合と似ていますが、関数で動作するため、クロス適用を学習しようとしていました。

上記のクエリでは、注文 d.id desc は 30 である最上位の 1 番目の ID のみを提供し、dept id = 30 の従業員を返す必要があるため、dept=30 のみを取る必要があると想定していますが、すべての行とすべての深い。

クエリの何が問題なのか、または相互適用の概念の解釈が間違っています。

4

3 に答える 3

1

ダミアンのコメントを拡張するには、内部クエリ:

select top 1 * from depttb1 d
where d.id = e.dept
order by d.id desc

外側のクエリのすべての行に対して実行されます。

select e.id, e.name, a.id
from emptb1 e

したがって、各行の内部クエリから常に一致が得られます。内部クエリが 1 回だけ実行されることを期待していたと思いますが、そうでAPPLYはありません。

したがって、ID が 1 で部門 ID が 10 の外部クエリから最初の行を取得すると、内部クエリは次のように変換されます。

select top 1 * from depttb1 d
where d.id = 10  //this is the dept id for the current row from your outer query
order by d.id desc
于 2013-12-16T14:55:43.823 に答える
-2

相互適用なしでこの問題を解決するには、サブクエリを使用します。ただし、あなたの例では、id値が増加していると仮定して入力された最後の部門が1行しか返されません。

-- Using a sub query to find max dept
select e.id, e.name
from emptb1 e
where e.dept in
(
select top 1 id 
from depttb1 
order by id desc
)

CROSS APPLYの背後にある考え方は、CROSS JOIN のようなものです。これにより、すべての行が返されます。テーブル値関数 (TVF) である動的管理ビュー (DMV) の多くで DBA によって使用されます。

あなたが望むのは、LEFT JOINのようなOUTER APPLYです。

select e.id, e.name
from emptb1 e
outer apply 
    (
    select top 1 d.id from depttb1 d order by d.id desc
    ) AS m (id)
where e.dept = m.id

これらの概念に関する私の記事をチェックしてください。

相互適用 - http://craftydba.com/?p=3767

外部適用 - http://craftydba.com/?p=3796

テーブル値関数 (インライン) - http://craftydba.com/?p=3733

テーブル値関数 (複数行) - http://craftydba.com/?p=3754

于 2013-12-16T14:41:14.717 に答える