SELEZIONA LIMIT 1 per valore colonna?


10

Diciamo che ho la seguente tabella

-----------------------------
| user_id   | comment       |
-----------------------------
| 2         | thats cool    |
| 2         | awesome       |
| 3         | i hate this   |
| 3         | okay          |
| 6         | this is weird |
| 6         | hello?        |
| 6         | what is it    |
| 9         | how are you   |
| 16        | too slow      |
| 16        | yes           |
| 17        | alrighty      |
-----------------------------

Come puoi selezionare una riga per user_id? Quindi i miei risultati sarebbero:

-----------------------------
| user_id   | comment       |
-----------------------------
| 2         | thats cool    |
| 3         | i hate this   |
| 6         | this is weird |
| 9         | how are you   |
| 16        | too slow      |
| 17        | alrighty      |
-----------------------------

Questo è possibile con una singola query efficiente? Oppure sono necessarie le selezioni secondarie? È possibile in qualche modo utilizzare DISTINCTsu una singola colonna?

Risposte:


9

Ecco a cosa GROUP BYserve. Ottieni una riga (per gruppo). In questo caso, mostrerà tutti distinti user_idvalori e per il resto delle colonne, si può (necessario) utilizzare funzioni di aggregazione come MIN(), MAX(), AVG(), SUM()come si avrà più di un valore per gruppo e può essere mostrata una sola.

SELECT
    user_id
  , MIN(comment) AS comment  -- it will show the first in alphabetical order  
                             -- you could also use MAX()
FROM
    tableX
GROUP BY
    user_id ;

MySQL consente anche la seguente soluzione non ortodossa, che restituirà un commento (più o meno casuale) per utente:

SELECT
    user_id
  , comment
FROM
    tableX
GROUP BY
    user_id ;

Quest'ultima query non funzionerà ma genererà un errore se la ONLY_FULL_GROUP_BYmodalità (più rigorosa) è abilitata. Nella versione 5.7 rilasciata di recente, questa modalità è quella predefinita e ANY_VALUE()viene fornita una nuova funzione . Per maggiori dettagli, consultare la pagina Gestione MySQL dellaGROUP BY pagina. La query può essere scritta ora:

SELECT
    user_id
  , ANY_VALUE(comment) AS comment
FROM
    tableX
GROUP BY
    user_id ;

Si noti che con la versione "non ortodossa" o utilizzando la ANY_VALUE()funzione recente , se si aggiungono più colonne SELECTnell'elenco, non è garantito che i loro valori provengano dalla stessa riga, solo da una riga nello stesso gruppo. Il modo in cui sono selezionati non è esattamente casuale, dipende dal piano di esecuzione e dagli indici utilizzati.


Esistono altri modi per specificare quale riga viene estratta per un ID_utente? Un modo per specificare un tipo di ORDINA PER?
Jake Wilson,

Inoltre MINe MAX?
ypercubeᵀᴹ

1
Quindi è più complesso. Vedi questa altra domanda: MySQL Query - Come ottenere i dati demografici più recenti?
ypercubeᵀᴹ

2
Troverai anche un sacco di problemi simili nel sito SO, sotto il [greatest-n-per-group]tag.
ypercubeᵀᴹ

1
@ T.BrianJones intendi nella query "non ortodossa", se aggiungi tutte le altre colonne nell'elenco SELECT? È il primo, potrebbero non appartenere alla stessa riga. Non è esattamente casuale ma i valori possono provenire da righe diverse (dallo stesso gruppo).
ypercubeᵀᴹ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.