Pilih di mana hitungan satu bidang lebih besar dari satu

100

Saya ingin melakukan sesuatu seperti ini:

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

Bagaimana saya bisa mencapai ini di MySql?

stevebot
sumber

Jawaban:

146

Gunakan HAVING, bukan WHEREklausa, untuk perbandingan hasil agregat.

Mengambil kueri pada nilai nominal:

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

Idealnya, harus ada GROUP BYdefinisi untuk penilaian yang tepat dalam HAVINGklausa, tetapi MySQL mengizinkan kolom tersembunyi dari GROUP BY ...

Apakah ini dalam persiapan untuk kendala unik someField? Sepertinya itu harus ...

OMG Ponies
sumber
11
Butuh GROUP BYpasti (kecuali ini adalah beberapa hal non standar MySQL)?
Martin Smith
@Martin Smith: Mengambil kueri pada nilai nominal; menangani masalah GROUP BY (termasuk fitur kolom tersembunyi).
OMG Ponies
"Sepertinya seharusnya ..." Kenapa? Saya membutuhkan pendidikan tentang ini :)
Dave
Jadi ini akan mengembalikan seluruh tabel jika berisi lebih dari 2 someFieldnilai bukan null atau hasil kosong jika tidak.
Martin Smith
@ Dave: Jika Anda berada dalam posisi di mana Anda harus secara berkala memeriksa & memperbaiki data yang buruk, tidakkah Anda ingin menghentikan situasi ini terjadi? MySQL menerapkan batasan unik sebagai indeks - untuk info lebih lanjut lihat dokumentasi 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
dandy_sql
sumber
3
satu-satunya peringatan di sini (setidaknya di 5.1.46-community MySQL Community Server (GPL)) adalah bahwa "Setiap tabel turunan harus memiliki aliasnya sendiri", yang akan membuat Anda sql terlihat seperti: PILIH nama pengguna, nonaktifkan dari (Pilih nama pengguna, hitung (nama pengguna) sebagai numb dari pelanggan GROUP BY username) sebagai my_table WHERE
numb
14

Anda juga dapat melakukan ini dengan bergabung sendiri:

SELECT t1.* FROM db.table t1
JOIN db.table t2 ON t1.someField = t2.someField AND t1.pk != t2.pk
Bill Karwin
sumber
11

Ini dia:

SELECT Field1, COUNT(Field1)
  FROM Table1 
 GROUP BY Field1
HAVING COUNT(Field1) > 1
ORDER BY Field1 desc
Nalan Madheswaran
sumber
4

Satu arah

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

Seperti yang dikatakan OMG Ponies, klausa memiliki adalah apa yang Anda cari. Namun, jika Anda berharap bahwa Anda akan mendapatkan baris diskrit daripada ringkasan ("memiliki" membuat ringkasan) - ini tidak dapat dilakukan dalam satu pernyataan. Anda harus menggunakan dua pernyataan dalam kasus itu.

Brent Arias
sumber
1
Tidak sepenuhnya benar - gunakan GROUP BY untuk memanipulasi apa yang digunakan HAVING.
OMG Ponies
1

Saya memberikan contoh pada Group By antara dua tabel di 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


pengguna4551254
sumber
1

Bagi saya, Tidak memiliki grup dengan hanya mengembalikan hasil kosong. Jadi saya kira memiliki grup untuk pernyataan memiliki cukup penting

Maham Khan
sumber
-2

Juga harus disebutkan bahwa "pk" harus menjadi bidang kunci. Gabung mandiri

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

oleh Bill Karwin memberi Anda semua catatan yang duplikat yang saya inginkan. Karena beberapa memiliki lebih dari dua, Anda bisa mendapatkan rekaman yang sama lebih dari sekali. Saya menulis semua ke tabel lain dengan bidang yang sama untuk menyingkirkan catatan yang sama dengan penekanan bidang kunci. Saya mencoba

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

di atas dulu. Data yang dikembalikan darinya hanya memberikan satu duplikat, kurang dari 1/2 dari apa yang diberikan kepada Anda tetapi hitungannya baik jika itu yang Anda inginkan.

Jim Blanchard
sumber
3
Ini sebenarnya bukan jawaban.
anon582847382