ステートメントを選択して特定のフィールドの重複を見つけます


415

SQLステートメントで複数のフィールドの重複を見つけるのを手伝ってくれませんか?

たとえば、擬似コードでは:

select count(field1,field2,field3) 
from table 
where the combination of field1, field2, field3 occurs multiple times

上記のステートメントから、複数のオカレンスがある場合、最初のレコードを除くすべてのレコードを選択したいと思います。


3
疑似コードがあいまいであり、最初に使用したくない順序に従って定義していません。いくつかのサンプルデータを提供することをお勧めします。
Unreason

回答:


840

複数のレコードがあるフィールドのリストを取得するには、..を使用できます。

select field1,field2,field3, count(*)
  from table_name
  group by field1,field2,field3
  having count(*) > 1

行を削除する方法の詳細については、このリンクを確認してください。

http://support.microsoft.com/kb/139444

編集:他のユーザーが述べたように、上のリンクのアプローチを使用する前に、「最初の行」を定義する方法を決定するための基準が必要です。これに基づいて、必要に応じて、order by句とサブクエリを使用する必要があります。いくつかのサンプルデータを投稿できれば、非常に役立ちます。


42

あなたは「最初のもの」と言っているので、あなたはあなたのデータにある種の順序があると思います。あなたのデータが何らかのフィールドで並べ替えられているとしましょうID

このSQLは、最初のエントリを除いて、重複するエントリを取得します。基本的に、(a)同じフィールドと(b)低いIDが存在する別の行が存在するすべての行を選択します。パフォーマンスは良くありませんが、問題を解決する可能性があります。

SELECT A.ID, A.field1, A.field2, A.field3
  FROM myTable A
 WHERE EXISTS (SELECT B.ID
                 FROM myTable B
                WHERE B.field1 = A.field1
                  AND B.field2 = A.field2
                  AND B.field3 = A.field3
                  AND B.ID < A.ID)

17

これは、SQL Server 2005で私が気に入っている楽しいソリューションです。「最初のレコードを除くすべてのレコードについて」とは、どの行が「最初」かを識別するために使用できる別の「id」列があることを意味します。

SELECT id
    , field1
    , field2
    , field3
FROM
(
    SELECT id
        , field1
        , field2
        , field3
        , RANK() OVER (PARTITION BY field1, field2, field3 ORDER BY id ASC) AS [rank]
    FROM table_name
) a
WHERE [rank] > 1

SQL Server 2008タグに気づきました。私の提案はまだ有効です。
Nick Vaccaro

1
問題のテーブルから削除する必要がある行も返すため、優れたソリューション
Realto619

1
PARTITION BYフィールドリストをPKフィールドのリストと考えると役立ちます
bkwdesign

6

重複する値を表示するには:

with MYCTE  as (
    select row_number() over ( partition by name  order by name) rown, *
    from tmptest  
    ) 
select * from MYCTE where rown <=1

3

SQL Server 2005以降を使用している場合(および質問のタグがSQL Server 2008を示している場合)、何らかの理由で結合を使用することが望ましくないか実用的でない場合は、ランキング関数を使用して最初のレコードの後に​​重複レコードを返すことができます。次の例は、これを実際に示したもので、調べた列のnull値でも機能します。

create table Table1 (
 Field1 int,
 Field2 int,
 Field3 int,
 Field4 int 
)

insert  Table1 
values    (1,1,1,1)
        , (1,1,1,2)
        , (1,1,1,3)
        , (2,2,2,1)
        , (3,3,3,1)
        , (3,3,3,2)
        , (null, null, 2, 1)
        , (null, null, 2, 3)

select    *
from     (select      Field1
                    , Field2
                    , Field3
                    , Field4
                    , row_number() over (partition by   Field1
                                                      , Field2
                                                      , Field3
                                         order by       Field4) as occurrence
          from      Table1) x
where     occurrence > 1

この例を実行すると、すべての「グループ」の最初のレコードが除外され、null値のレコードが適切に処理されることに注意してください。

グループ内のレコードの順序付けに使用できる列がない場合は、partition-by列をorder-by列として使用できます。


1
CREATE TABLE #tmp
(
    sizeId Varchar(MAX)
)

INSERT  #tmp 
    VALUES ('44'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46')


SELECT * FROM #tmp
DECLARE @SqlStr VARCHAR(MAX)

SELECT @SqlStr = STUFF((SELECT ',' + sizeId
              FROM #tmp
              ORDER BY sizeId
              FOR XML PATH('')), 1, 1, '') 


SELECT TOP 1 * FROM (
select items, count(*)AS Occurrence
  FROM dbo.Split(@SqlStr,',')
  group by items
  having count(*) > 1
  )K
  ORDER BY K.Occurrence DESC    

0

このクエリを試して、各SELECTステートメントの数を数えます。

select field1,count(field1) as field1Count,field2,count(field2) as field2Counts,field3, count(field3) as field3Counts
from table_name
group by field1,field2,field3
having count(*) > 1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.