小编典典

无法绑定多部分标识符

all

我在 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;

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

阅读 44

收藏
2022-06-07

共1个答案

小编典典

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

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

以下是您的查询大纲:

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

您可能期望它的行为如下:

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

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

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

也就是说,正如您可能已经理解的那样,dkcd专门针对band
only连接,然后连接的结果与子句b结合a并进一步过滤。在这种情况下,子句中的WHERE任何引用都是无效的,此时是未知的。这就是您收到错误消息的原因。a``ON``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

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

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

2022-06-07