2011-09-16 18 views
5

Ho una tabella con più righe che hanno gli stessi dati. Ho usato SELECT DISTINCT per ottenere una riga univoca e funziona perfettamente. Ma quando uso ORDER BY con SELECT DISTINCT mi dà dati non ordinati.Come funziona SELECT DISTINCT in MySQL?

Qualcuno può dirmi quanto distinto funziona?

In base a quali criteri viene selezionata la riga?

+0

Quali sono le query che si sta tentando di eseguire? – srivani

+0

@srivani: seleziona un ID distinto dalla tabella in cui id2 = 12312 ordine per ora desc. – insomiac

+0

So che è troppo tardi ma non c'è ancora una risposta accettata, quindi voglio sapere se l'OP vuole ancora una risposta per qualcosa che non è coperto nelle risposte date? –

risposta

1

Se si specifica SELECT DISTINCT, verranno fornite tutte le righe, eliminando i duplicati dal set di risultati. Per "duplicati" intendo le righe in cui tutti i campi hanno gli stessi valori. Per esempio, supponiamo di avere una tabella che assomiglia:

id | num 
-------------- 
1 | 1 
2 | 3 
3 | 3 

SELECT DISTINCT * sarebbe restituire tutte le righe di cui sopra, mentre SELECT DISTINCT num sarebbe tornato due file:

num 
----- 
1 
3 

Si noti che la riga attuale riga (ad esempio: se è la riga 2 o la riga 3) che seleziona è irrilevante, in quanto il risultato sarebbe indistinguibile.

Infine, DISTINCT dovrebbe non influire sul modo in cui ORDER BY funziona.

Riferimento: MySQL SELECT statement

+2

Sembra che lo faccia in MySQL. Leggi questo: http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html – Icarus

+0

è quasi come un bug :) – Randy

+0

@Icarus Quali ottimizzazioni esegue è irrilevante, purché il set di risultati ritorna come te lo aspetti. – NullUserException

2

Dal tuo commento precedente, la query che si sta tentando di eseguire è

Select distinct id from table where id2 =12312 order by time desc. 

Come mi aspettavo, qui è il vostro problema. La colonna selezionata e l'ordine per colonna sono diversi. Le tue righe di output sono ordinate per tempo, ma quell'ordine non deve necessariamente essere conservato nella colonna id. Ecco un esempio.

id | id2 | time 
------------------- 
1 | 12312 | 34 
2 | 12312 | 12 
3 | 12312 | 48 

Se si esegue

SELECT * FROM table WHERE id2=12312 ORDER BY time DESC 

si otterrà il seguente risultato

id | id2 | time 
------------------- 
2 | 12312 | 12 
1 | 12312 | 34 
3 | 12312 | 48 

Ora, se si seleziona solo la colonna id da questo, si otterrà

id 
-- 
2 
1 
3 

Ecco perché i risultati sono non ordinato.

+0

Cosa succede se si hanno più ID (per es: id = 2 e id = 1 si è verificato più volte) quale sarà selezionato facendo la ricerca in base al tempo? – insomiac

+0

Se si esegue "Seleziona ID distinto dalla tabella in cui id2 = 12312 ordine per ora desc", i duplicati verranno rimossi. Se si esegue "Select id from table where id2 = 12312 order by time desc", i risultati conterranno duplicati. Quindi tutte le occorrenze dell'id verranno restituite. – srivani

+0

grazie per aver risposto, per esempio se voglio ottenere id recenti come per volta e se sto facendo una desc per volta con id distinti. Non funziona con mysql. Sai quanto distinto funziona con l'ordine? – insomiac

0

Il comportamento descritto si verifica quando si è ORDER BY un'espressione non presente nella clausola SELECT. Lo standard SQL non consente una simile query ma MySQL è meno severo e lo consente.

Proviamo un esempio:

SELECT DISTINCT colum1, column2 
FROM table1 
WHERE ... 
ORDER BY column3 

Diciamo che il contenuto della tabella table1 è:

id | column1 | column2 | column3 
----+---------+---------+--------- 
    1 | A  | B  | 1 
    2 | A  | B  | 5 
    3 | X  | Y  | 3 

senza la clausola ORDER BY, i ritorni di query di cui sopra seguenti due record (senza ORDER BY l'ordine non è garantito):

column1 | column2 
---------+--------- 
A  | B 
X  | Y 

Ma con ORDER BY column3 anche l'ordine non è garantito.

La clausola DISTINCT opera sui valori delle espressioni presenti nella clausola SELECT. Se la riga n. 1 viene elaborata per prima (A, B) viene inserita nel set di risultati ed è associata alla riga n. Quindi, quando viene elaborata la riga n. 2, i valori delle espressioni SELECT producono il record (A, B) già presente nel set di risultati. A causa di DISTINCT viene eliminato. La riga n. 3 produce (X, Y) che viene inserita anche nel set di risultati. Quindi, la clausola ORDER BY column3 ordina i record nel set di risultati come (A, B), (X, Y).

Ma se riga # 2 è elaborato prima riga # 1 allora, seguendo la stessa logica esposto nel paragrafo precedente, i record nel set di risultati sono ordinati come (X, Y), (A, B).

Non esiste alcuna regola imposta al motore del database sull'ordine in cui elabora le righe quando viene eseguita una query. Il database è libero di elaborare le righe in qualsiasi ordine che ritenga sia meglio per le prestazioni.

La query non è valida SQL e il fatto che possa restituire risultati diversi utilizzando gli stessi dati di input lo dimostra.

Problemi correlati