2016-06-02 9 views
0

メーリングリストを持っていて、重複しているエントリが多数あります。私はそれらを削除することができるように重複を見つけることを試みている。以下の完全なクエリを実行すると、テーブル内のすべての項目が取得されます(142,000 +)。サブクエリを実行すると、5768行しか得られません。どの重複行を削除するかを決めるには、重複行ごとにすべての列が必要です。すべての行を返す完全なクエリが発生する原因は何ですか?SQL existsすべての行を返します

あなたはそれをこのようにしなければならない
select * from Mailinglist 
where exists 
(select count(*), mailaddress, CenterName 
from Mailinglist 
group by MailAddress, CenterName 
having count(*)>1) 
+2

なぜ内部クエリを実行しないのですか? 'Having'句を持つものは? – codingbiz

+0

@codingbizサブクエリは、削除後に少なくとも1つのデータが必要なため、1つを除いて重複して削除された結果を持っています。右は、 'オフセット2を使用して次の100行'を使用できます。 –

+0

サブクエリーは外部クエリなぜ外部クエリからすべての行を返します。 –

答えて

3

EXISTSを使用して
select t1.*, t2.cnt 
from Mailinglist t1 
join (
    select count(*) as cnt, mailaddress, CenterName 
    from Mailinglist 
    group by MailAddress, CenterName 
    having count(*)>1 
) t2 ON t1.MailAddress = t2.MailAddress and t1.CenterName = t2.CenterName 

は、レコードだけで、存在をチェック、またはない:サブクエリが1つまたは複数のレコードが返された場合、その後、EXISTStrueに評価。

2

EXISTSは、それに続くクエリ内に1つのレコードが存在する場合はtrueを返します。 あなたが探していることは、サブクエリが行を返す場合EXISTSがtrueを返すためです

select * from Mailinglist 
where mailaddress IN 
(
    select mailaddress 
    from Mailinglist 
    group by MailAddress, CenterName 
    having count(*)>1 
) 
0

です。サブクエリ が1つ以上の行を返しているため、EXISTS条件の場合はTRUEが返されます。重複してMailingListを取得するには

、あなただけのサブクエリを実行することができます。

SELECT 
    COUNT(*), 
    mailaddress, 
    CenterName 
FROM Mailinglist 
GROUP BY 
    MailAddress, CenterName 
HAVING COUNT(*) > 1 

重複を削除するには、ROW_NUMBERを使用することができます。

WITH Cte AS(
    SELECT *, 
     rn = ROW_NUMBER() OVER(PARTITION BY MailAddress, Centername ORDER BY (SELECT NULL)) 
    FROM MailingList 
) 
DELETE FROM Cte WHERE rn > 1 

ただ、これに応じて、ORDER BY句を置き換えます保持したい複製の行。

0

サブクエリにフィルタリングはありません。

SELECT  * 
FROM   Mailinglist AS ML 
WHERE  EXISTS 
     (SELECT  COUNT(*) AS Expr1, mailaddress, CenterName 
     FROM   Mailinglist AS CNT 
     WHERE  (ML.MailAddress = CNT.MailAddress) AND (ML.CenterName = CNT.CenterName) 
     GROUP BY mailaddress, CenterName 
     HAVING   (COUNT(*) > 1)) 
関連する問題