Как выбрать каждую строку, где значение столбца НЕ является отличительным


154

Мне нужно выполнить оператор выбора, который возвращает все строки, где значение столбца не отличается (например, EmailAddress).

Например, если таблица выглядит следующим образом:

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

Мне нужен запрос для возврата:

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

Я прочитал много постов и пробовал разные запросы безрезультатно. Запрос, который я считаю, должен работать ниже. Может кто-нибудь предложить альтернативу или сказать, что может быть не так с моим запросом?

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

Ответы:


263

Это значительно быстрее, чем EXISTSспособ:

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

1
Эй, я знаю, что этому ответу 7 лет, но если вы все еще рядом, не могли бы вы объяснить, как он работает? Решил и мою проблему!
Лу

4
Использование HAVINGздесь вместо второго SELECT...WHEREприводит к тому, что это будет один запрос вместо второго параметра, который выполняет этот второй SELECT...WHEREвызов много раз. Смотрите больше здесь: stackoverflow.com/q/9253244/550975
Серж Саган

Я получаю позорную [EmailAddress] must appear in the GROUP BY clause or be used in an aggregate functionошибку. Единственное исправление - редактирование sql_mode?
Владимир Бобыр

[EmailAddress]В GROUP BYстатье
Серж Саган

51

Что неверно в вашем запросе, так это то, что вы группируете по электронной почте и имени, что формирует группу из каждого уникального набора электронной почты и имени, объединенных вместе и, следовательно,

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

рассматриваются как 3 разные группы, а скорее все принадлежат к одной группе.

Пожалуйста, используйте запрос, как указано ниже:

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

21
Мне нравится, что вы также включили объяснение того, что не так с оригинальным запросом, в отличие от принятого ответа.

12

Как насчет

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

незначительное улучшение для отображения количества как «дупс»: выберите CustomerName, count (1) как дупс из группы «Клиенты» по CustomerName, имеющему count (1)>
1`

8

Просто для удовольствия, вот еще один способ:

;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 для версии CTE Мы не должны повторяться в коде, зачем повторяться в SQL, если нам больше не нужно.
yzorg

1
Я использую _count для столбца count (более num). Я постоянно использую подчеркивание, когда столбцы сталкиваются с ключевыми словами SQL, такими как _default, _type, _sum и т. Д.
yzorg

4

Вместо того, чтобы использовать подзапросы, где условие, которое увеличит время запроса, когда записи огромны.

Я бы предложил использовать Inner Join как лучший вариант решения этой проблемы.

Учитывая ту же таблицу, это может дать результат

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

Для еще лучших результатов я бы предложил вам использовать CustomerIDлюбое другое поле вашей таблицы. Дублирование CustomerNameвозможно.


-2

Ну, есть небольшое изменение, чтобы найти не четкие строки ..

SELECT EmailAddress, CustomerName FROM Customers WHERE EmailAddress NOT IN
(SELECT EmailAddress FROM Customers GROUP BY EmailAddress HAVING COUNT(*) > 1)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.