SQL / mysql – Seleziona distinto / UNICO ma restituisce tutte le colonne?

SELECT DISTINCT field1, field2, field3, ...... FROM table 

Sto provando a realizzare la seguente istruzione sql ma voglio che restituisca tutte le colonne sia ansible? Qualcosa di simile a:

 SELECT DISTINCT field1, * from table 

Stai cercando un gruppo di:

 select * from table group by field1 

Che a volte può essere scritto con una distinta dichiarazione:

 select distinct on field1 * from table 

Sulla maggior parte delle piattaforms, tuttavia, nessuna delle precedenti funzionerà perché il comportamento sulle altre colonne non è specificato. (Il primo funziona in MySQL, se è quello che stai usando.)

È ansible recuperare i campi distinti e continuare a selezionare una singola riga arbitraria ogni volta.

Su alcune piattaforms (ad es. PostgreSQL, Oracle, T-SQL) questo può essere fatto direttamente utilizzando le funzioni della finestra:

 select * from ( select *, row_number() over (partition by field1 order by field2) as row_number from table ) as rows where row_number = 1 

Su altri (MySQL, SQLite), dovrai scrivere sottoquery che ti faranno unire l’intera tabella con se stesso ( esempio ), quindi non raccomandato.

Dalla frase della tua domanda, capisco che vuoi selezionare i valori distinti per un determinato campo e che per ognuno di questi valori devono essere elencati tutti gli altri valori di colonna nella stessa riga. La maggior parte dei DBMS non lo consentiranno né con DISTINCT né con GROUP BY , poiché il risultato non è determinato.

Pensalo in questo modo: se il tuo field1 verifica più di una volta, quale valore di field2 verrà elencato (dato che hai lo stesso valore per field1 in due righe ma due valori distinti di field2 in quelle due righe).

È tuttavia ansible utilizzare le funzioni di aggregazione (esplicitamente per ogni campo che si desidera visualizzare) e utilizzare un GROUP BY invece di DISTINCT :

 SELECT field1, MAX(field2), COUNT(field3), SUM(field4), .... FROM table GROUP BY field1 

Se ho capito bene il tuo problema, è simile a quello che ho appena avuto. Vuoi essere in grado di limitare l’usabilità di DISTINCT a un campo specificato, piuttosto che applicarlo a tutti i dati.

Se utilizzi GROUP BY senza una funzione di aggregazione, che mai campo GROUP BY sarà il tuo DISTINCT archiviato.

Se fai la tua domanda:

 SELECT * from table GROUP BY field1; 

Mostrerà tutti i risultati basati su una singola istanza di field1.

Ad esempio, se hai un tavolo con nome, indirizzo e città. Una singola persona ha più indirizzi registrati, ma si desidera solo un singolo indirizzo per la persona, è ansible interrogare come segue:

 SELECT * FROM persons GROUP BY name; 

Il risultato sarà che solo un’istanza di quel nome apparirà con il suo indirizzo, e l’altra verrà omessa dalla tabella risultante. Attenzione: se i tuoi file hanno valori atomici come firstName, lastName che desideri raggruppare da entrambi.

 SELECT * FROM persons GROUP BY lastName, firstName; 

perché se due persone hanno lo stesso cognome e si raggruppa solo per cognome, una di queste persone verrà omessa dai risultati. È necessario tenere in considerazione queste cose. Spero che questo ti aiuti.

 SELECT c2.field1 , field2 FROM (SELECT DISTINCT field1 FROM dbo.TABLE AS C ) AS c1 JOIN dbo.TABLE AS c2 ON c1.field1 = c2.field1 

Questa è davvero una bella domanda. Ho già letto alcune risposte utili qui, ma probabilmente posso aggiungere una spiegazione più precisa.

Ridurre il numero di risultati della query con un’istruzione GROUP BY è semplice se non si richiedono ulteriori informazioni. Supponiamo che tu abbia la seguente tabella “posizioni”.

 --country-- --city-- France Lyon Poland Krakow France Paris France Marseille Italy Milano 

Ora la query

 SELECT country FROM locations GROUP BY country 

risulterà in:

 --country-- France Poland Italy 

Tuttavia, la seguente query

 SELECT country, city FROM locations GROUP BY country 

… genera un errore in MS SQL, perché in che modo il tuo computer potrebbe sapere quale delle tre città francesi “Lione”, “Parigi” o “Marsiglia” vuoi leggere sul campo alla destra di “Francia”?

Per correggere la seconda query, è necessario aggiungere queste informazioni. Un modo per farlo è usare le funzioni MAX () o MIN (), selezionando il valore più big o più piccolo tra tutti i candidati. MAX () e MIN () non si applicano solo ai valori numerici, ma confrontano anche l’ordine alfabetico dei valori stringa.

 SELECT country, MAX(city) FROM locations GROUP BY country 

risulterà in:

 --country-- --city-- France Paris Poland Krakow Italy Milano 

o:

 SELECT country, MIN(city) FROM locations GROUP BY country 

risulterà in:

 --country-- --city-- France Lyon Poland Krakow Italy Milano 

Queste funzioni sono una buona soluzione purché tu stia bene selezionando il tuo valore da entrambe le estremità dell’ordine alfabetico (o numerico). Ma cosa succede se questo non è il caso? Supponiamo di aver bisogno di un valore con una certa caratteristica, ad esempio iniziando con la lettera “M”. Ora le cose si complicano.

L’unica soluzione che ho trovato finora è quella di inserire l’intera query in una sottoquery e di build la colonna aggiuntiva al di fuori di essa a mano:

 SELECT countrylist.*, (SELECT TOP 1 city FROM locations WHERE country = countrylist.country AND city like 'M%' ) FROM (SELECT country FROM locations GROUP BY country) countrylist 

risulterà in:

 --country-- --city-- France Marseille Poland NULL Italy Milano 

Grande domanda @aryaxt – puoi dire che è stata una grande domanda perché l’hai chiesto 5 anni fa e oggi ci sono incappato in esso cercando di trovare la risposta!

Ho appena provato a modificare la risposta accettata per includerla, ma nel caso in cui la mia modifica non lo faccia in:

Se il tuo tavolo non fosse così grande e supponendo che la tua chiave primaria fosse un numero intero auto-incrementante, potresti fare qualcosa del genere:

 SELECT table.* FROM table --be able to take out dupes later LEFT JOIN ( SELECT field, MAX(id) as id FROM table GROUP BY field ) as noDupes on noDupes.id = table.id WHERE //this will result in only the last instance being seen noDupes.id is not NULL 

Puoi farlo con una clausola WITH .

Per esempio:

 WITH c AS (SELECT DISTINCT a, b, c FROM tableName) SELECT * FROM tableName r, c WHERE c.rowid=r.rowid AND ca=ra AND cb=rb AND cc=rc 

Ciò consente anche di selezionare solo le righe selezionate nella query delle clausole WITH .

Per SQL Server è ansible utilizzare dense_rank e funzioni di windowing aggiuntive per ottenere tutte le righe AND colonne con valori duplicati su colonne specificate. Ecco un esempio …

 with t as ( select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r1' union all select col1 = 'c', col2 = 'b', col3 = 'a', other = 'r2' union all select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r3' union all select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r4' union all select col1 = 'c', col2 = 'b', col3 = 'a', other = 'r5' union all select col1 = 'a', col2 = 'a', col3 = 'a', other = 'r6' ), tdr as ( select *, total_dr_rows = count(*) over(partition by dr) from ( select *, dr = dense_rank() over(order by col1, col2, col3), dr_rn = row_number() over(partition by col1, col2, col3 order by other) from t ) x ) select * from tdr where total_dr_rows > 1 

Questo sta prendendo un conteggio delle righe per ciascuna combinazione distinta di col1, col2 e col3.

 SELECT * FROM tblname GROUP BY duplicate_values ORDER BY ex.VISITED_ON DESC LIMIT 0 , 30 

in ORDER BY ho appena messo l’esempio qui, puoi anche aggiungere il campo ID in questo

Suggerirei di usare

 SELECT * from table where field1 in ( select distinct field1 from table ) 

in questo modo se si ha lo stesso valore in campo1 su più righe, verranno restituiti tutti i record.

Aggiungi GROUP BY al campo per il quale vuoi verificare la presenza di duplicati

 SELECT field1, field2, field3, ...... FROM table GROUP BY field1 

campo1 verrà controllato per escludere i record duplicati

o puoi chiedere come

 SELECT * FROM table GROUP BY field1 

i record duplicati di field1 sono esclusi da SELECT

Può essere fatto dalla query interna

 $query = "SELECT * FROM (SELECT field FROM table ORDER BY id DESC) as rows GROUP BY field"; 

Basta includere tutti i campi nella clausola GROUP BY.

 SELECT * from table where field in (SELECT distinct field from table) 

SELECT DISTINCT FIELD1, FIELD2, FIELD3 FROM TABLE1 funziona se i valori di tutte e tre le colonne sono univoci nella tabella.

Se, ad esempio, hai più valori identici per il nome, ma il cognome e altre informazioni nelle colonne selezionate sono diversi, il record verrà incluso nel set di risultati.