Seleziona dove il conteggio di un campo è maggiore di uno


100

Voglio fare qualcosa del genere:

SELECT * 
  FROM db.table 
 WHERE COUNT(someField) > 1

Come posso ottenere questo risultato in MySql?

Risposte:


146

Utilizzare la clausola HAVING, not WHERE, per il confronto dei risultati aggregati.

Prendendo la query al valore nominale:

SELECT * 
  FROM db.table 
HAVING COUNT(someField) > 1

Idealmente, dovrebbe esserci una GROUP BYdefinizione per una corretta valutazione nella HAVINGclausola, ma MySQL consente colonne nascoste da GROUP BY ...

Questo è in preparazione per un vincolo unico su someField? Sembra che dovrebbe essere ...


11
Serve GROUP BYsicuramente (a meno che non si tratti di una cosa non standard di MySQL)?
Martin Smith

@ Martin Smith: ha preso la query al valore nominale; risolto il problema GROUP BY (inclusa la funzionalità delle colonne nascoste).
Pony OMG

"Sembra che dovrebbe essere ..." Perché? Ho bisogno di istruzione su questo :)
Dave

Quindi questo restituirà l'intera tabella se contiene più di 2 someFieldvalori non nulli o un set di risultati vuoto in caso contrario.
Martin Smith

@ Dave: Se fossi in una posizione in cui dovessi controllare e correggere periodicamente dati errati, non vorresti impedire che la situazione si verifichi in primo luogo? MySQL implementa un vincolo univoco come indice - per maggiori informazioni vedere la documentazione CREATE INDEX
OMG Ponies

18
SELECT username, numb from(
Select username, count(username) as numb from customers GROUP BY username ) as my_table
WHERE numb > 3

3
l'unico avvertimento qui (almeno in MySQL Community Server (GPL) della community 5.1.46) è che "Ogni tabella derivata deve avere il proprio alias", che ti farà sembrare sql: SELECT username, numb from (Select username, count (username) as numb from customers GROUP BY username) as my_table WHERE numb> 3
D_K

14

Puoi farlo anche con un self-join:

SELECT t1.* FROM db.table t1
JOIN db.table t2 ON t1.someField = t2.someField AND t1.pk != t2.pk

11

Ecco qui:

SELECT Field1, COUNT(Field1)
  FROM Table1 
 GROUP BY Field1
HAVING COUNT(Field1) > 1
ORDER BY Field1 desc

4

Senso unico

SELECT t1.* 
FROM db.table t1
WHERE exists 
      (SELECT *
      FROM db.table t2 
      where t1.pk != t2.pk 
      and t1.someField = t2.someField)

1

Come affermato da OMG Ponies, la clausola di avere è ciò che stai cercando. Tuttavia, se speravi di ottenere righe discrete invece di un riepilogo (l '"avere" crea un riepilogo), non è possibile farlo in una singola istruzione. In questo caso devi usare due affermazioni.


1
Non del tutto vero: usa GROUP BY per manipolare ciò che HAVING sta usando.
OMG Ponies

1

Faccio un esempio su Group By tra due tabelle in Sql:

Select cn.name,ct.name,count(ct.id) totalcity from city ct left join country cn on ct.countryid = cn.id Group By cn.name,ct.name Having totalcity > 2



1

Per me, non avere un gruppo ha restituito solo un risultato vuoto. Quindi immagino che avere un gruppo per la dichiarazione di avere è piuttosto importante


-2

Va anche detto che il "pk" dovrebbe essere un campo chiave. L'autoadesione

SELECT t1.* FROM db.table t1
JOIN db.table t2 ON t1.someField = t2.someField AND t1.pk != t2.pk 

di Bill Karwin ti do tutti i record che sono duplicati, che è quello che volevo. Poiché alcuni ne hanno più di due, puoi ottenere lo stesso record più di una volta. Ho scritto tutto su un'altra tabella con gli stessi campi per eliminare gli stessi record sopprimendo i campi chiave. Provai

SELECT * FROM db.table HAVING COUNT(someField) > 1

prima sopra. I dati restituiti da esso danno solo uno dei duplicati, meno della metà di ciò che ti dà, ma il conteggio è buono se è tutto ciò che vuoi.


3
Questa non è davvero una risposta.
anon582847382
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.