Cách chọn mỗi hàng trong đó giá trị cột không khác biệt


154

Tôi cần chạy một câu lệnh chọn trả về tất cả các hàng trong đó giá trị của một cột không khác biệt (ví dụ: EmailAddress).

Ví dụ: nếu bảng trông như dưới đây:

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

Tôi cần truy vấn để trả về:

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

Tôi đã đọc nhiều bài viết và thử các truy vấn khác nhau nhưng không có kết quả. Các truy vấn mà tôi tin rằng nên làm việc là dưới đây. Ai đó có thể đề xuất một giải pháp thay thế hoặc cho tôi biết điều gì có thể sai với truy vấn của tôi không?

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

Câu trả lời:


263

Điều này nhanh hơn đáng kể so với EXISTScách:

SELECT [EmailAddress], [CustomerName] FROM [Customers] WHERE [EmailAddress] IN
  (SELECT [EmailAddress] FROM [Customers] GROUP BY [EmailAddress] HAVING COUNT(*) > 1)

1
Này, tôi biết câu trả lời này đã 7 tuổi, nhưng nếu bạn vẫn ở đó, bạn có phiền giải thích nó hoạt động như thế nào không? Giải quyết vấn đề của tôi là tốt!
Lou

4
Sử dụng HAVINGở đây thay vì một giây SELECT...WHEREkhiến đây là một truy vấn duy nhất, thay vì tùy chọn thứ hai thực hiện SELECT...WHEREcuộc gọi thứ hai đó nhiều lần. Xem thêm tại đây: stackoverflow.com/q/9253244/550975
Serj Sagan

Tôi nhận được [EmailAddress] must appear in the GROUP BY clause or be used in an aggregate functionlỗi khét tiếng . Là sửa chữa duy nhất - chỉnh sửa sql_mode?
Volodymyr Bobyr

[EmailAddress]IS trong GROUP BYmệnh đề
Serj Sagan

51

Điều không đúng với truy vấn của bạn là bạn đang nhóm theo email và tên, tạo thành một nhóm của mỗi nhóm email và tên duy nhất kết hợp với nhau và do đó

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

được coi là 3 nhóm khác nhau chứ không phải tất cả thuộc về 1 nhóm duy nhất.

Vui lòng sử dụng truy vấn như được đưa ra dưới đây:

select emailaddress,customername from customers where emailaddress in
(select emailaddress from customers group by emailaddress having count(*) > 1)

21
Tôi thích rằng bạn cũng bao gồm một lời giải thích về những gì sai với truy vấn ban đầu, không giống như câu trả lời được chấp nhận.

12

Làm thế nào về

SELECT EmailAddress, CustomerName FROM Customers a
WHERE Exists ( SELECT emailAddress FROM customers c WHERE a.customerName != c.customerName AND a.EmailAddress = c.EmailAddress)

11
select CustomerName,count(1) from Customers group by CustomerName having count(1) > 1

cải tiến nhỏ để hiển thị số lượng là "dups": chọn Tên khách hàng, đếm (1) làm số lần nhảy từ nhóm Khách hàng theo Tên khách hàng có số đếm (1)> 1`
DynamicDan

8

Để giải trí, đây là một cách khác:

;with counts as (
    select CustomerName, EmailAddress,
      count(*) over (partition by EmailAddress) as num
    from Customers
)
select CustomerName, EmailAddress
from counts
where num > 1

1
+1 cho phiên bản CTE Chúng ta không nên lặp lại chính mình trong mã, tại sao lại lặp lại chính mình trong SQL nếu chúng ta không phải làm vậy nữa.
yzorg 17/8/2016

1
Tôi sử dụng _count cho cột đếm (trên num). Tôi luôn sử dụng dấu gạch dưới khi các cột xảy ra xung đột với các từ khóa SQL như _default, _type, _sum, v.v.
yzorg 17/8/2016

4

Thay vì sử dụng các truy vấn phụ trong điều kiện sẽ tăng thời gian truy vấn trong đó các bản ghi là rất lớn.

Tôi sẽ đề nghị sử dụng Inside Join như một lựa chọn tốt hơn cho vấn đề này.

Xem xét cùng một bảng điều này có thể cho kết quả

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

Để có kết quả tốt hơn, tôi sẽ đề nghị bạn sử dụng CustomerIDhoặc bất kỳ trường duy nhất nào trong bảng của bạn. Sao chép CustomerNamelà có thể.


-2

Vâng, có một sự thay đổi nhỏ để tìm các hàng không khác biệt ..

SELECT EmailAddress, CustomerName FROM Customers WHERE EmailAddress NOT IN
(SELECT EmailAddress FROM Customers GROUP BY EmailAddress HAVING COUNT(*) > 1)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.