Ho visto la seguente query MySQL che utilizza DISTINCT e GROUP BY insieme:
SELECT DISTINCT user_id, post_id, post_content FROM some_table GROUP BY post_id, user_id HAVING post_content LIKE "%abc%";
Ecco uno scenario da seguire con la query: ogni utente ha un ID univoco, user_id
, e può creare più post identificati da un ID univoco, post_id
. Ogni post conterrebbe del testo.
Lho trovato confuso (dopo essere arrivato da Oracle DB) e avevo le seguenti domande:
- Qual è il significato dellutilizzo di
GROUP BY
senza eseguire alcuna aggregazione? - Qual è il significato di cambiare lordine delle colonne in
SELECT
rispetto aGROUP BY
? - Qual è il significato di omettere la terza colonna da
GROUP BY
? - Perché
DISTINCT
utilizzato insieme aGROUP BY
? Loperazione distinta viene eseguita dopo che tutti i raggruppamenti sono stati eseguiti sul risultato finale o prima?
Commenti
Risposta
annuncio 1) Vecchi database mysql e quando disabiliti ONLY_FULL_GROUP_BY , puoi fare questa query e se i post_content sono tutti uguali noterai che mysql restituisce un valore casuale non deterministico .
ad 2) none what so ever
ad 3) programmazione pigra e si verifica un errore quando si abilita ONLY_FULL_GROUP_BY
ad 4) No, mostrerebbe tutti i post_content che sono collegati a user_id, post_id simile a addind post_content al gruppo da
Come Strawberry ha già detto questa query non “t ha un senso
Risposta
La folle capacità di consentire il gruppo parziale nelle versioni precedenti di MyS QL, deve essere uno dei principali contendenti per la maggior confusione causata nel settore IT.
Data la tabella:
CREATE TABLE t ( x int not null primary key , y int not null ); INSERT INTO t (x,y) VALUES (1,1),(1,2);
Laffermazione
SELECT x, y FROM t GROUP BY x
potrebbe significare (1,1) o (1,2) e MySQL ne restituirebbe casualmente uno di questi. DISTINCT non ha importanza in questo caso, il risultato è ancora in-deterministico.
SQL92 richiedeva che tutte le colonne nella clausola select (eccetto le colonne aggregate e le costanti) facessero parte della clausola GROUP BY.
SQL99 ha allentato un po questa restrizione e ci ha permesso di escludere le colonne di GROUP BY che sono funzionalmente dipendenti dalle colonne rimanenti. Cioè
CREATE TABLE t ( x int not null primary key , y int not null ); SELECT x, y FROM t GROUP by x
sarebbe valido poiché y è f.d. di x
Abbastanza sorprendentemente (per me) la versione successiva di MySQL è la migliore della classe quando si tratta di implementare la versione SQL99. Non lho controllato ultimamente, ma quando ho creato MySQL ha gestito bene scenari abbastanza complicati, dove PostgreSQL ha gestito solo quelli banali.
Per rispondere alle tue domande
1)
SELECT x, y FROM t GROUP BY x, y
significa che la combinazione di x, y è un gruppo. In tutte le possibili situazioni posso pensare che sia lo stesso di:
SELECT DISTINCT x, y FROM t
Dal momento che vengono valutati logicamente in momenti diversi, potrebbe esserci qualche caso dangolo in cui potrebbero effettivamente differire (non riesco a pensarne uno però)
2) Nessuno , a questo proposito sono un insieme di colonne, quindi non cè ordine
3) Vedi sopra.
4) Lordine logico di valutazione di una query SQL è:
FROM, JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY FETCH FIRST
quindi si suppone che GROUP BY venga valutato prima di DISTINCT. Non riesco a pensare a una situazione in cui ciò sarebbe importante.
Nella tua query Sospetto che qualcuno abbia ottenuto risultati confusi e abbia cercato di ottenere un altro risultato utilizzando DISTINCT. Probabilmente sono stati fortunati (o sfortunati) a ottenere il risultato che previsto, quindi il DISTINCT è rimasto. Il bug però è ancora presente
GROUP BY
non ha alcuna importanza (tranne che nelle versioni precedenti implicava lo stessoORDER BY
. IlSELECT
lordine è importante solo nella disposizione delle colonne nelloutput.