Mat*_*mov 15 sql join inner-join subquery sql-server-2008
架构:
create table TableA (A1 int)
create table TableB (B1 int, B2 int)
create table TableC (C1 int)
Run Code Online (Sandbox Code Playgroud)
有问题的查询:
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.C1) d ON d.C2=b.B2
INNER JOIN OtherTable ON OtherTable.Foo=d.C1
Run Code Online (Sandbox Code Playgroud)
构建此模式并在SQL Server 2008下的SQLFiddle中运行查询会导致:
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.C1) d ON d.C2=b.B2
Run Code Online (Sandbox Code Playgroud)
对子查询使用CROSS APPLY而不是INNER JOIN可以解决问题
有什么问题?
编辑:我添加了"TOP 1",这是真正的查询的一部分,它是问题的相关部分.
Edit2:有关该问题的更多信息.
您不能从另一个已联接子查询内部的联接访问别名。您将需要使用以下内容在两个列/表上连接子查询:
SELECT *
FROM TableA a
INNER JOIN TableB b
ON b.B1=a.A1
INNER JOIN
(
SELECT *
FROM TableC c
) d
ON d.C2=b.B2
AND d.C1 = b.B1
Run Code Online (Sandbox Code Playgroud)
或者可以这样写:
SELECT *
FROM TableA a
INNER JOIN TableB b
ON b.B1=a.A1
INNER JOIN TableC c
ON c.C2=b.B2
AND c.C1 = b.B1
Run Code Online (Sandbox Code Playgroud)
您不能将 fromJOIN
子句引用到 JOIN 的另一部分。
用这个代替。
SELECT *
FROM TableA a
INNER JOIN TableB b
ON b.B1=a.A1
INNER JOIN TableC c
ON d.C2=b.B2
AND c.C1=b.B1
Run Code Online (Sandbox Code Playgroud)
编辑
SELECT *
FROM TableA a
INNER JOIN TableB b ON b.B1=a.A1
WHERE b.B2 = (SELECT TOP 1 c.C2
FROM TableC c
WHERE c.C1=b.B1 ORDER BY c.C1)
Run Code Online (Sandbox Code Playgroud)
为了在 JOIN-s 中进一步使用,TableC
您可以使用它。
SELECT *
FROM TableA a
INNER JOIN TableB b
ON b.B1=a.A1
INNER JOIN
(
SELECT
ROW_NUMBER() OVER (PARTITION BY C1 ORDER BY C2) RN,
C2
--, other columns fromTableC if needed
FROM TableC
) CC
ON b.B2 = CC.C2
AND CC.RN = 1
Run Code Online (Sandbox Code Playgroud)