我在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;
您混合了隐式连接和显式连接。这是允许的,但您需要知道如何正确地做到这一点。
问题是,显式连接(使用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。
您混合了隐式连接和显式连接。这是允许的,但您需要知道如何正确地做到这一点。
问题是,显式连接(使用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。