Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Impossibile associare l'identificatore multiparte

Stai mescolando join impliciti con join espliciti. È consentito, ma devi essere consapevole di come farlo correttamente.

Il fatto è che i join espliciti (quelli che vengono implementati usando il JOIN parola chiave) hanno la precedenza su quelli impliciti (i join 'virgola', dove la condizione di join è specificata in WHERE clausola).

Ecco uno schema della tua richiesta:

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

Probabilmente ti aspetti che si comporti in questo modo:

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

ovvero la combinazione di tabelle a e b è unito alla tabella dkcd . In effetti, quello che sta succedendo è

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

ovvero, come forse avrai già capito, dkcd è unito specificamente a b e solo b , quindi il risultato del join viene combinato con a e filtrato ulteriormente con WHERE clausola. In questo caso, qualsiasi riferimento a a nel ON la clausola non è valida, a è sconosciuto a quel punto. Ecco perché ricevi il messaggio di errore.

Se fossi in te, probabilmente proverei a riscrivere questa query e una possibile soluzione potrebbe essere:

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

Qui le tabelle a e b vengono prima uniti, quindi il risultato viene unito a dkcd . Fondamentalmente, questa è la tua stessa query, utilizzando solo una sintassi diversa per uno dei join, il che fa una grande differenza:il riferimento a.maxa nel dkcd la condizione di unione di ora è assolutamente valida.

Come ha correttamente notato @Aaron Bertrand, dovresti probabilmente qualificare maxa con uno specifico alias, probabilmente a , nel ORDER BY clausola.