我在 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;
您将隐式连接与显式连接混合在一起。这是允许的,但你需要知道如何正确地做到这一点。
问题是,显式连接(使用JOIN关键字实现的连接)优先于隐式连接(“逗号”连接,连接条件在WHERE子句中指定)。
JOIN
WHERE
以下是您的查询大纲:
SELECT … FROM a, b LEFT JOIN dkcd ON … WHERE …
您可能期望它的行为如下:
SELECT … FROM (a, b) LEFT JOIN dkcd ON … WHERE …
也就是表的组合,a并b与表连接dkcd。事实上,正在发生的事情是
a
b
dkcd
SELECT … FROM a, (b LEFT JOIN dkcd ON …) WHERE …
也就是说,正如您可能已经理解的那样,dkcd专门针对band only连接,然后连接的结果与子句b结合a并进一步过滤。在这种情况下,子句中的WHERE任何引用都是无效的,此时是未知的。这就是您收到错误消息的原因。a``ON``a
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
这里的表a和b首先连接,然后结果连接到dkcd。基本上,这与您的查询相同,只是对其中一个联接使用了不同的语法,这有很大的不同: ‘ 的联接条件中的引用a.maxa现在dkcd绝对有效。
a.maxa
正如@Aaron Bertrand 正确指出的那样,您可能应该在子句中maxa使用特定别名来限定。a``ORDER BY
maxa
a``ORDER BY