Pilih pernyataan untuk menemukan duplikat di bidang tertentu


415

Bisakah Anda membantu saya dengan pernyataan SQL untuk menemukan duplikat di beberapa bidang?

Misalnya, dalam kode pseudo:

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

dan dari pernyataan di atas jika ada beberapa kejadian saya ingin memilih setiap catatan kecuali yang pertama .


3
kode pseudo Anda ambigu, ditambah Anda tidak menentukan urutan yang tidak Anda inginkan terlebih dahulu. saya sarankan Anda memberikan beberapa sampel data.
masuk akal

Jawaban:


840

Untuk mendapatkan daftar bidang yang berisi banyak catatan, Anda bisa menggunakan ..

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

Periksa tautan ini untuk informasi lebih lanjut tentang cara menghapus baris.

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

Sunting: Seperti yang disebutkan oleh pengguna lain, harus ada kriteria untuk memutuskan bagaimana Anda mendefinisikan "baris pertama" sebelum Anda menggunakan pendekatan dalam tautan di atas. Berdasarkan hal itu Anda harus menggunakan pesanan dengan klausa dan sub kueri jika diperlukan. Jika Anda dapat memposting beberapa sampel data, itu akan sangat membantu.


42

Anda menyebutkan "yang pertama", jadi saya berasumsi bahwa Anda memiliki semacam pemesanan pada data Anda. Mari kita asumsikan bahwa data Anda dipesan oleh beberapa bidang ID.

SQL ini akan membuat Anda entri duplikat kecuali yang pertama. Itu pada dasarnya memilih semua baris yang baris lain dengan (a) bidang yang sama dan (b) ada ID yang lebih rendah. Performa tidak akan bagus, tetapi mungkin bisa menyelesaikan masalah Anda.

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

Ini adalah solusi yang menyenangkan dengan SQL Server 2005 yang saya sukai. Saya akan berasumsi bahwa dengan "untuk setiap catatan kecuali yang pertama", maksud Anda ada kolom "id" lain yang bisa kita gunakan untuk mengidentifikasi baris mana yang "pertama".

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

Hanya memperhatikan tag SQL Server 2008. Senang saran saya masih valid.
Nick Vaccaro

1
Solusi yang sangat baik karena juga mengembalikan baris yang perlu dihapus dari tabel yang bersangkutan
Realto619

1
itu membantu untuk memikirkan daftar bidang PARTISI OLEH sebagai daftar bidang PK
bkwdesign

6

Untuk melihat nilai duplikat:

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

3

Jika Anda menggunakan SQL Server 2005 atau lebih baru (dan tag untuk pertanyaan Anda menunjukkan SQL Server 2008), Anda dapat menggunakan fungsi peringkat untuk mengembalikan catatan duplikat setelah yang pertama jika menggunakan gabungan kurang diinginkan atau tidak praktis karena beberapa alasan. Contoh berikut menunjukkan ini dalam tindakan, di mana ia juga bekerja dengan nilai nol di kolom yang diperiksa.

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

Perhatikan setelah menjalankan contoh ini bahwa catatan pertama dari setiap "grup" dikecualikan, dan bahwa catatan dengan nilai nol ditangani dengan benar.

Jika Anda tidak memiliki kolom yang tersedia untuk memesan catatan dalam grup, Anda dapat menggunakan kolom partisi-per sebagai kolom urutan-oleh.


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

coba kueri ini untuk mendapatkan sepratley count dari setiap pernyataan 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.