Як вибрати кожну рядок, де значення стовпця НЕ чітко


154

Мені потрібно запустити оператор select, який повертає всі рядки, де значення стовпця не відрізняється (наприклад, 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
Serj Sagan

Я отримую сумнозвісну [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

незначне посилення, щоб показати кількість "дуп": виберіть Ім'я клієнта, рахуйте (1) як дупсів із групи Клієнтів за клієнтським іменем, маючи кількість (1)> 1`
DynamicDan

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" (понад число). Я послідовно використовую підкреслення, коли стовпці стикаються з такими ключовими словами 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.