Chọn câu lệnh để tìm các mục trùng lặp trên các trường nhất định


415

Bạn có thể giúp tôi với các câu lệnh SQL để tìm các bản sao trên nhiều trường không?

Ví dụ: trong mã giả:

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

và từ tuyên bố trên nếu có nhiều lần xuất hiện, tôi muốn chọn mọi bản ghi ngoại trừ bản ghi đầu tiên .


3
mã giả của bạn không rõ ràng, cộng với việc bạn không xác định thứ tự theo đó bạn không muốn đầu tiên. tôi đề nghị bạn cung cấp một số dữ liệu mẫu.
Không hợp lý

Câu trả lời:


840

Để có được danh sách các trường có nhiều bản ghi, bạn có thể sử dụng ..

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

Kiểm tra liên kết này để biết thêm thông tin về cách xóa các hàng.

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

Chỉnh sửa: Như những người dùng khác đã đề cập, cần có một tiêu chí để quyết định cách bạn xác định "hàng đầu tiên" trước khi bạn sử dụng phương pháp tiếp cận trong liên kết ở trên. Dựa vào đó, bạn sẽ cần sử dụng một đơn đặt hàng theo mệnh đề và truy vấn phụ nếu cần. Nếu bạn có thể đăng một số dữ liệu mẫu, nó sẽ thực sự có ích.


42

Bạn đề cập đến "cái đầu tiên", vì vậy tôi cho rằng bạn có một số loại đặt hàng trên dữ liệu của bạn. Giả sử rằng dữ liệu của bạn được sắp xếp theo một số lĩnh vực ID.

SQL này sẽ giúp bạn có các mục trùng lặp ngoại trừ mục đầu tiên. Về cơ bản, nó chọn tất cả các hàng mà một hàng khác có (a) cùng các trường và (b) ID thấp hơn tồn tại. Hiệu suất sẽ không tốt, nhưng nó có thể giải quyết vấn đề của bạn.

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

Đây là một giải pháp thú vị với SQL Server 2005 mà tôi thích. Tôi sẽ giả định rằng "cho mỗi bản ghi ngoại trừ bản ghi đầu tiên", bạn có nghĩa là có một cột "id" khác mà chúng ta có thể sử dụng để xác định hàng nào là "đầu tiên".

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

Chỉ cần chú ý thẻ SQL Server 2008. Vui mừng đề nghị của tôi vẫn còn hiệu lực.
Nick Vaccaro

1
Giải pháp tuyệt vời vì nó cũng trả về các hàng cần xóa khỏi bảng được đề cập
Realto619

1
nó giúp nghĩ về danh sách trường
THAM GIA B BYNG

6

Để xem các giá trị trùng lặp:

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

3

Nếu bạn đang sử dụng SQL Server 2005 trở lên (và các thẻ cho câu hỏi của bạn chỉ ra SQL Server 2008), bạn có thể sử dụng các hàm xếp hạng để trả về các bản ghi trùng lặp sau lần đầu tiên nếu sử dụng phép nối ít mong muốn hoặc không thực tế vì một số lý do. Ví dụ sau đây cho thấy điều này trong hành động, nơi nó cũng hoạt động với các giá trị null trong các cột được kiểm tra.

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

Lưu ý sau khi chạy ví dụ này rằng bản ghi đầu tiên trong số mọi "nhóm" bị loại trừ và các bản ghi có giá trị null được xử lý đúng cách.

Nếu bạn không có sẵn một cột để sắp xếp các bản ghi trong một nhóm, bạn có thể sử dụng các cột theo phân vùng làm các cột theo thứ tự.


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

hãy thử truy vấn này để có số sepratley của mỗi câu lệnh CHỌN:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.