无法绑定多部分标识符 - 子查询

Posted

技术标签:

【中文标题】无法绑定多部分标识符 - 子查询【英文标题】:The multi-part identifier could not be bound - SubQuery 【发布时间】:2013-01-17 08:56:16 【问题描述】:

架构:

create table TableA (A1 int)
create table TableB (B1 int, B2 int)
create table TableC (C1 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.C1) d ON d.C2=b.B2
INNER JOIN OtherTable ON OtherTable.Foo=d.C1

构建此架构并在 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

对子查询使用 CROSS APPLY 而不是 INNER JOIN 可以解决问题

有什么问题?

编辑:我添加了“TOP 1”,它是真实查询的一部分,它是问题的相关部分。

Edit2:有关问题的更多信息。

【问题讨论】:

好的。查看您的子查询。您按 C1 过滤,然后按 C1 排序。什么意思?我想你一定要ORDER BYC2。 这是对真实查询的抽象 但是你扭曲了逻辑。请参阅我的更新答案。 使用 CROSS APPLY(或在我的情况下使用 OUTER APPLY 而不是 LEFT JOIN)...为我解决了这个问题! CROSS APPLY 对我来说是新的,但解决了我的挑战!感谢您发布此内容。 【参考方案1】:

您不能从另一个连接子查询中的连接访问别名。您将需要使用以下连接两个列/表的子查询:

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

或者可以写成:

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

【讨论】:

You cannot access an alias inside of a subquery. 我不这么认为。 SELECT * FROM Table1 T1 WHERE someColumn IN (SELECT someColumn FROM Table2 WHERE T1.Id = Table1_Id ) 从另一个连接子查询内部的连接 - 我相信他们的观点【参考方案2】:

您不能从 JOIN 子句引用 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

已编辑

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)

要在 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

【讨论】:

如果在进一步的内部连接中需要“SELECT TOP 1”怎么办? 使用“ROW_NUMBER()”是犯罪行为。 Using "ROW_NUMBER()" is criminal. 为什么?

以上是关于无法绑定多部分标识符 - 子查询的主要内容,如果未能解决你的问题,请参考以下文章

Crystal Reports中的“多部分标识符无法绑定”与SQL表达式/子查询

SQL 错误 - 无法绑定多部分标识符“CF.OBJ”

无法绑定多部分标识符“alias.field”

SQL 错误 无法绑定多部分标识符

SQL 错误:无法绑定多部分标识符

无法绑定多部分标识符“SR_DOC_HDR.DOC_VERS_NO”