我在SO上看到过类似的错误,但我没有找到解决我的问题的方法。 我有一个SQL查询像:

SELECT DISTINCT
        a.maxa ,
        b.mahuyen ,
        a.tenxa ,
        b.tenhuyen ,
        ISNULL(dkcd.tong, 0) AS tongdkcd
FROM    phuongxa a ,
        quanhuyen b
        LEFT OUTER JOIN ( SELECT    maxa ,
                                    COUNT(*) AS tong
                          FROM      khaosat
                          WHERE     CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                                              AND
                                                              'Sep 5 2011'
                          GROUP BY  maxa
                        ) AS dkcd ON dkcd.maxa = a.maxa
WHERE   a.maxa <> '99'
        AND LEFT(a.maxa, 2) = b.mahuyen
ORDER BY maxa;

当我执行这个查询时,错误结果是: 无法绑定多部分标识符“a.maxa”。为什么? P/s:如果我把查询分成2个单独的查询,它运行正常。

SELECT DISTINCT
        a.maxa ,
        b.mahuyen ,
        a.tenxa ,
        b.tenhuyen
FROM    phuongxa a ,
        quanhuyen b
WHERE   a.maxa <> '99'
        AND LEFT(a.maxa, 2) = b.mahuyen
ORDER BY maxa;

and

SELECT  maxa ,
        COUNT(*) AS tong
FROM    khaosat
WHERE   CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                        AND     'Sep 5 2011'
GROUP BY maxa;

当前回答

在我的例子中,问题原来是我给表设置的别名。对于SQL Server来说,“oa”似乎是不可接受的。

其他回答

在我的例子中,问题原来是我给表设置的别名。对于SQL Server来说,“oa”似乎是不可接受的。

在SELECT语句中的列名之间缺少逗号也可能导致此错误。

eg:

SELECT MyCol1, MyCol2 MyCol3 FROM SomeTable;

您混合了隐式连接和显式连接。这是允许的,但您需要知道如何正确地做到这一点。

问题是,显式连接(使用JOIN关键字实现的连接)优先于隐式连接('逗号'连接,其中连接条件在where子句中指定)。

以下是你的问题的提纲:

SELECT
  …
FROM a, b LEFT JOIN dkcd ON …
WHERE …

你可能希望它是这样的:

SELECT
  …
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …

也就是说,表a和b的组合与表dkcd连接。事实上,正在发生的事情是

SELECT
  …
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …

也就是说,正如您可能已经理解的那样,dkcd是专门针对b且仅针对b连接的,然后连接的结果与a结合,并使用WHERE子句进一步筛选。在这种情况下,ON子句中对a的任何引用都是无效的,此时a是未知的。这就是为什么您会得到错误消息。

如果我是你,我可能会尝试重写这个查询,一个可能的解决方案可能是:

SELECT DISTINCT
  a.maxa,
  b.mahuyen,
  a.tenxa,
  b.tenhuyen,
  ISNULL(dkcd.tong, 0) AS tongdkcd
FROM phuongxa a
  INNER JOIN quanhuyen b ON LEFT(a.maxa, 2) = b.mahuyen
  LEFT OUTER JOIN (
    SELECT
      maxa,
      COUNT(*) AS tong
    FROM khaosat
    WHERE CONVERT(datetime, ngaylap, 103) BETWEEN 'Sep 1 2011' AND 'Sep 5 2011'
    GROUP BY maxa
  ) AS dkcd ON dkcd.maxa = a.maxa
WHERE a.maxa <> '99'
ORDER BY a.maxa

这里首先连接表a和b,然后将结果连接到dkcd。基本上,这是与您的查询相同的查询,只是对其中一个连接使用了不同的语法,这产生了很大的不同:dkcd的连接条件中的引用a.maxa现在是绝对有效的。

正如@Aaron Bertrand所正确指出的,您可能应该在ORDER BY子句中使用特定的别名限定maxa,可能是a。

当以错误的方式在查询中使用模式(dbo)时,有时会发生此错误。

例如,如果你写:

select dbo.prd.name
from dbo.product prd

您将得到错误。

在这种情况下,将其更改为:

select prd.name
from dbo.product prd

对我有用的是将WHERE子句更改为SELECT子查询

来自:

    DELETE FROM CommentTag WHERE [dbo].CommentTag.NoteId = [dbo].FetchedTagTransferData.IssueId

TO:

    DELETE FROM CommentTag WHERE [dbo].CommentTag.NoteId = (SELECT NoteId FROM FetchedTagTransferData)