Fondamentalmente perché sono definiti per scopi diversi. La clausola WHERE
riguarda il filtraggio dei record e la clausola HAVING
è progettata per il filtraggio con le funzioni di aggregazione (GROUP BY
). Nella seconda query viene utilizzato un filtro implicito GROUP BY
, quindi ad esempio, se si aggiunge un'altra colonna alla clausola SELECT
, si otterranno risultati diversi.
EDIT basato su correzione Martin Smith
HAVING
stata creata per permettere il filtraggio delle righe risultanti di un GROUP BY
. Se non è specificato GROUP BY
, l'intero risultato è considerato un gruppo.
Se non viene specificato un <where clause>
né <group by clause>
, quindi sia T il risultato del precedente <from clause>
o
... il gruppo è l'intera tabella se non è specificato <group by clause>
EDIT 2 Ora per quanto riguarda l'ALIAS:
Il disciplinare della clausola WHERE per quanto riguarda le colonne riferimenti nella condizione di ricerca dice questo:
Ogni <column reference>
direttamente contenuta nel <search condition>
è inequivocabilmente riferimento una colonna di T o essere un riferimento esterno.
Fare riferimento a: 7.6 <where clause>
, Sintassi Regola 1.
Il disciplinare della clausola HAVING per quanto riguarda le colonne riferimenti nella condizione di ricerca dice questo:
Ogni <column reference>
direttamente contenuta nel <search condition>
deve inequivocabilmente riferimento una colonna di raggruppamento di T o essere un esterno riferimento.
Vedi anche: Regola 7.8 <having clause>
, Sintassi 1.
E un colonna di raggruppamento è definito come:
Una colonna di riferimento in un <group by clause>
è una colonna di raggruppamento.
In conclusione il WHERE
deve fare riferimento a una colonna della tabella e la clausola HAVING
deve fare riferimento a una colonna di raggruppamento del gruppo di righe.
(Second Informal Review Draft) ISO/IEC 9075:1992, Database Language SQL- July 30, 1992
Si tratta di un'estensione MySQL allo standard. Ad esempio, non è possibile fare riferimento agli alias di colonne in 'having' in SQL Server. –