列の値が明確でないすべての行を選択する方法


154

列の値が明確でないすべての行(EmailAddressなど)を返すselectステートメントを実行する必要があります。

たとえば、テーブルが次のようになっているとします。

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歳であることを知っていますが、あなたがまだそこにいるなら、それがどのように機能するか説明していただけませんか?私の問題も解決しました!
Lou

4
HAVING2番目の代わりにhere を使用すると、2 SELECT...WHERE番目のSELECT...WHERE呼び出しを何度も実行する2番目のオプションではなく、1つのクエリになります。詳細はこちら:stackoverflow.com/q/9253244/550975
Serj Sagan

悪名高い[EmailAddress] must appear in the GROUP BY clause or be used in an aggregate functionエラーが発生します。唯一の修正-編集sql_modeですか?
Volodymyr Bobyr

[EmailAddress]GROUP BY条項に含まれている
Serj Sagan

51

クエリで間違っているのは、メールと名前でグループ化していることです。これにより、メールと名前の一意の各セットがグループ化され、一緒に結合されます。

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

すべてが1つの単一グループに属するのではなく、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

countを「dups」として表示するためのマイナーな機能強化:CustomerName、count(1)を、Counter(1)> 1`を持つCustomerNameによるCustomersグループからの重複として選択
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
CTEバージョンの+1コードで繰り返してはいけません。もう必要がない場合は、SQLで繰り返してください。
yzorg

1
カウント列に_countを使用しています(num以上)。列がなど_default、_type、_sum、のようなSQLのキーワードと衝突に起こるとき、私は一貫して、アンダースコアを使用
yzorg

4

レコードが巨大な場合にクエリ時間を増加させるwhere条件でサブクエリを使用するのではなく。

この問題のより良いオプションとして、内部結合を使用することをお勧めします。

同じテーブルを考えると、これは結果を与える可能性があります

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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.