考虑以下架构:
create table TableA (A1 int)
create table TableB (B1 int, B2 int)
create table TableC (C1 int, C2 int)
create table TableD (D1 int)
以及以下查询:
SELECT *
FROM TableA a
INNER JOIN TableB b ON b.B1=a.A1
INNER JOIN (SELECT TOP 1 *
FROM TableC c
WHERE c.C1=b.B1 ORDER BY c.C2) foo ON foo.C1=a.A1
INNER JOIN TableD d ON d.D1=foo.C1
在 SQL Fiddle (SQL Server 2008) 中,我得到以下结果:
The multi-part identifier "b.B1" could not be bound.: SELECT * FROM TableA a INNER JOIN TableB b ON b.B1=a.A1 INNER JOIN (SELECT TOP 1 * FROM TableC c WHERE c.C1=b.B1 ORDER BY c.C2) foo ON foo.C1=a.A1 INNER JOIN TableD d ON d.D1=foo.C1
但是用CROSS APPLY替换子查询的INNER JOIN可以解决问题:
SELECT *
FROM TableA a
INNER JOIN TableB b ON b.B1=a.A1
CROSS APPLY (SELECT TOP 1 *
FROM TableC c
WHERE c.C1=b.B1 AND c.C1=a.A1 ORDER BY c.C2) foo
INNER JOIN TableD d ON d.D1=foo.C1
我的问题是:
1)为什么第一次查询失败?
2)为什么第二个查询没有失败?
3) CROSS APPLY特定于 SQL Server。哪一个是这个问题的 SQL 标准解决方案?
重要提示:不要试图理解 TableA、...、TableD 背后的逻辑。它们只是对更复杂查询的抽象(读起来很糟糕)。我想你会明白这个问题的。