I'já vi erros semelhantes na SO, mas não'não encontro uma solução para o meu problema. Eu tenho uma consulta SQL como:
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;
Quando eu executo esta consulta, o resultado do erro é:
O identificador multi-partes "a.maxa" não pôde ser vinculado. Porquê?
P/s: se eu dividir a consulta em 2 consultas individuais, ela funciona bem.
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;
e
SELECT maxa ,
COUNT(*) AS tong
FROM khaosat
WHERE CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
AND 'Sep 5 2011'
GROUP BY maxa;
Você está misturando junções implícitas com junções explícitas. Isso é permitido, mas você precisa estar ciente de como fazer isso corretamente.
O problema é que as joinings explícitas (aquelas que são implementadas utilizando a palavra-chave JOIN
) têm precedência sobre as implícitas (o 'comma' joinins, onde a condição de join é especificada na cláusula WHERE
).
Aqui's um esboço da sua consulta:
SELECT
…
FROM a, b LEFT JOIN dkcd ON …
WHERE …
Provavelmente estás à espera que ele se comporte assim:
SELECT
…
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …
ou seja, a combinação das tabelas a' e
b' é unida à tabela `dkcd'. Na verdade, o que's está acontecendo é
SELECT
…
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …
isto é, como você já deve ter entendido, dkcd
é unido especificamente contra b
e apenas b
, então o resultado da união é combinado com a
e filtrado ainda mais com a cláusula WHERE
. Neste caso, qualquer referência a a
na cláusula ON
é inválida, a
é desconhecida nesse ponto. É por isso que você está recebendo a mensagem de erro.
Se eu fosse você, provavelmente tentaria reescrever esta consulta, e uma possível solução poderia ser:
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
Aqui as tabelas a' e
b' são unidas primeiro, depois o resultado é unido ao dkcd'. Basicamente, esta é a mesma consulta que a sua, utilizando apenas uma sintaxe diferente para uma das junções, o que faz uma grande diferença: a referência
a.maxana condição de junção
dkcd`'s é agora absolutamente válida.
Como @Aaron Bertrand observou corretamente, você provavelmente deve qualificar maxa
com um apelido específico, provavelmente a
, na cláusula ORDER BY
.
Às vezes este erro ocorre quando você usa o seu esquema (dbo) na sua consulta de uma forma errada.
por exemplo, se você escrever:
select dbo.prd.name
from dbo.product prd
você vai receber o erro.
Nestas situações, muda para:
select prd.name
from dbo.product prd
I'sou novo em SQL, mas deparei-me com este problema num curso que estava a fazer e descobri que atribuir a consulta ao projecto ajudou especificamente a eliminar o erro multi-partes. Por exemplo, o projeto que eu criei foi o CTU SQL Project, então eu me certifiquei de começar meu script com USE [CTU SQL Project] como minha primeira linha, como abaixo.
USE [CTU SQL Project]
SELECT Advisors.First_Name, Advisors.Last_Name...and so on.