Cara Memilih Setiap Baris Di Mana Nilai Kolom TIDAK Berbeda

154

Saya perlu menjalankan pernyataan pilih yang mengembalikan semua baris di mana nilai kolom tidak berbeda (mis. Alamat Email).

Misalnya, jika tabelnya terlihat seperti di bawah ini:

CustomerName     EmailAddress
Aaron            aaron@gmail.com
Christy          aaron@gmail.com
Jason            jason@gmail.com
Eric             eric@gmail.com
John             aaron@gmail.com

Saya perlu kueri untuk kembali:

Aaron            aaron@gmail.com
Christy          aaron@gmail.com
John             aaron@gmail.com

Saya telah membaca banyak posting dan mencoba berbagai pertanyaan tanpa hasil. Kueri yang saya yakin harus berfungsi adalah di bawah ini. Dapatkah seseorang menyarankan alternatif atau memberi tahu saya apa yang mungkin salah dengan permintaan saya?

select EmailAddress, CustomerName from Customers
group by EmailAddress, CustomerName
having COUNT(distinct(EmailAddress)) > 1
Belalang
sumber

Jawaban:

263

Ini secara signifikan lebih cepat daripada EXISTScaranya:

SELECT [EmailAddress], [CustomerName] FROM [Customers] WHERE [EmailAddress] IN
  (SELECT [EmailAddress] FROM [Customers] GROUP BY [EmailAddress] HAVING COUNT(*) > 1)
Serj Sagan
sumber
1
Hei, saya tahu jawaban ini berumur 7 tahun, tetapi jika Anda masih ada, maukah Anda menjelaskan bagaimana cara kerjanya? Memecahkan masalah saya juga!
Lou
4
Menggunakan di HAVINGsini alih-alih yang kedua SELECT...WHEREmenyebabkan ini menjadi permintaan tunggal, alih-alih opsi kedua yang mengeksekusi SELECT...WHEREpanggilan kedua itu berkali-kali. Lihat lebih lanjut di sini: stackoverflow.com/q/9253244/550975
Serj Sagan
Saya mendapatkan [EmailAddress] must appear in the GROUP BY clause or be used in an aggregate functionkesalahan terkenal . Apakah satu - satunya perbaikan - pengeditan sql_mode?
Volodymyr Bobyr
[EmailAddress]IS dalam GROUP BYklausa
Serj Sagan
51

Hal yang salah dengan kueri Anda adalah bahwa Anda mengelompokkan berdasarkan email dan nama, yang membentuk grup dari setiap rangkaian email dan nama unik yang digabungkan menjadi satu dan karenanya

aaron and aaron@gmail.com
christy and aaron@gmail.com
john and aaron@gmail.com

diperlakukan sebagai 3 kelompok yang berbeda, tetapi semua milik 1 kelompok tunggal.

Silakan gunakan kueri seperti yang diberikan di bawah ini:

select emailaddress,customername from customers where emailaddress in
(select emailaddress from customers group by emailaddress having count(*) > 1)
Berpengalaman
sumber
21
Saya suka bahwa Anda juga menyertakan penjelasan tentang apa yang salah dengan permintaan asli, tidak seperti jawaban yang diterima.
12

Bagaimana tentang

SELECT EmailAddress, CustomerName FROM Customers a
WHERE Exists ( SELECT emailAddress FROM customers c WHERE a.customerName != c.customerName AND a.EmailAddress = c.EmailAddress)
Marc
sumber
11
select CustomerName,count(1) from Customers group by CustomerName having count(1) > 1
Nisar
sumber
peningkatan kecil untuk menunjukkan jumlah sebagai "dups": pilih CustomerName, hitung (1) sebagai dups dari grup Pelanggan oleh CustomerName yang memiliki hitungan (1)> 1`
DynamicDan
8

Hanya untuk bersenang-senang, inilah cara lain:

;with counts as (
    select CustomerName, EmailAddress,
      count(*) over (partition by EmailAddress) as num
    from Customers
)
select CustomerName, EmailAddress
from counts
where num > 1
Chad
sumber
1
+1 untuk versi CTE Kita tidak boleh mengulangi diri kita sendiri dalam kode, mengapa mengulangi diri kita dalam SQL jika kita tidak perlu lagi.
yzorg
1
Saya menggunakan _count untuk kolom jumlah (lebih dari jumlah). Saya secara konsisten menggunakan garis bawah ketika kolom bertabrakan dengan kata kunci SQL seperti _default, _type, _sum, dll.
yzorg
4

Alih-alih menggunakan sub kueri di kondisi mana yang akan meningkatkan waktu kueri di mana catatan sangat besar.

Saya menyarankan untuk menggunakan Inner Join sebagai opsi yang lebih baik untuk masalah ini.

Mempertimbangkan tabel yang sama ini bisa memberikan hasil

SELECT EmailAddress, CustomerName FROM Customers as a 
Inner Join Customers as b on a.CustomerName <> b.CustomerName and a.EmailAddress = b.EmailAddress

Untuk hasil yang lebih baik, saya sarankan Anda menggunakan CustomerIDatau bidang unik apa pun dari tabel Anda. Duplikasi CustomerNamedimungkinkan.

Naveen Kishan
sumber
-2

Yah ada sedikit perubahan untuk menemukan baris yang tidak berbeda ..

SELECT EmailAddress, CustomerName FROM Customers WHERE EmailAddress NOT IN
(SELECT EmailAddress FROM Customers GROUP BY EmailAddress HAVING COUNT(*) > 1)
Rashmi Ranjan Ransingh
sumber