Jeg har sett lignende feil på SO, men jeg finner ikke en løsning på problemet mitt. Jeg har en SQL-spørring som:
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;
Når jeg utfører denne spørringen, er feilresultatet:
Den flerdelte identifikatoren "a.maxa" kunne ikke bindes. Hvorfor?
P / s: Hvis jeg deler spørringen i 2 individuelle spørringer, kjører den ok.
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;
og
SELECT maxa ,
COUNT(*) AS tong
FROM khaosat
WHERE CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
AND 'Sep 5 2011'
GROUP BY maxa;
Du blander implisitte sammenføyninger med eksplisitte sammenføyninger. Det er tillatt, men du må være klar over hvordan du gjør det på riktig måte.
Saken er at eksplisitte sammenføyninger (de som er implementert ved hjelp av nøkkelordet JOIN
) har forrang over implisitte ('komma' sammenføyninger, der sammenføyningsbetingelsen er spesifisert i WHERE
-klausulen).
Her er en oversikt over spørringen din:
SELECT
…
FROM a, b LEFT JOIN dkcd ON …
WHERE …
Du forventer sannsynligvis at det skal oppføre seg slik:
SELECT
…
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …
det vil si at kombinasjonen av tabellene a
og b
slås sammen med tabellen dkcd
. Det som faktisk skjer, er følgende
SELECT
…
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …
det vil si, som du kanskje allerede har forstått, dkcd
er sammenføyd spesifikt mot b
og bare b
, deretter kombineres resultatet av sammenføyningen med a
og filtreres videre med WHERE
-klausulen. I dette tilfellet er enhver referanse til a
i ON
-klausulen ugyldig, a
er ukjent på det tidspunktet. Det er derfor du får feilmeldingen.
Hvis jeg var deg, ville jeg sannsynligvis prøve å omskrive denne spørringen, og en mulig løsning kan være:
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
Her sammenføyes tabellene a
og b
først, deretter sammenføyes resultatet til dkcd
. I utgangspunktet er dette den samme spørringen som din, bare med en annen syntaks for en av sammenføyningene, noe som utgjør en stor forskjell: referansen a.maxa
i dkcd
's sammenføyningsbetingelse er nå absolutt gyldig.
Som @Aaron Bertrand riktig har bemerket, bør du sannsynligvis kvalifisere maxa
med et bestemt alias, sannsynligvis a
, i ORDER BY
klausulen.
Noen ganger oppstår denne feilen når du bruker skjemaet (dbo) i spørringen på feil måte.
for eksempel hvis du skriver:
select dbo.prd.name
from dbo.product prd
vil du få feilen.
I disse situasjonene endrer du det til:
select prd.name
from dbo.product prd
Jeg er ny i SQL, men kom over dette problemet i et kurs jeg tok og fant ut at å tilordne spørringen til prosjektet spesifikt bidro til å eliminere feilen i flere deler. For eksempel var prosjektet jeg opprettet CTU SQL Project, så jeg sørget for at jeg startet skriptet mitt med USE [CTU SQL Project] som min første linje som nedenfor.
USE [CTU SQL Project]
SELECT Advisors.First_Name, Advisors.Last_Name...and so on.