Выберите оператор, чтобы найти дубликаты на определенных полях - PullRequest
408 голосов
/ 14 декабря 2010

Можете ли вы помочь с инструкциями SQL найти дубликаты в нескольких полях?

Например, в псевдокоде:

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

и из приведенного выше оператора , если естьнесколько вхождений Я хотел бы выбрать каждую запись, кроме первой .

Ответы [ 7 ]

830 голосов
/ 14 декабря 2010

Чтобы получить список полей, для которых есть несколько записей, вы можете использовать ..

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

Проверьте эту ссылку для получения дополнительной информации о том, как удалить строки.

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

Редактировать: Как упоминали другие пользователи, должен быть критерий для определения того, как вы определяете «первые строки», прежде чем использовать подход по ссылке выше. Исходя из этого, вам нужно будет использовать заказ по предложению и подзапрос, если это необходимо. Если вы можете опубликовать пример данных, это действительно поможет.

42 голосов
/ 14 декабря 2010

Вы упомянули "первый", поэтому я предполагаю, что у вас есть какой-то порядок в ваших данных. Предположим, что ваши данные упорядочены по какому-то полю ID.

Этот SQL должен получить дубликаты, кроме первой. Он в основном выбирает все строки, для которых существует другая строка с (а) одинаковыми полями и (б) более низким идентификатором. Производительность не будет хорошей, но она может решить вашу проблему.

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 голосов
/ 14 декабря 2010

Это забавное решение с 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
6 голосов
/ 29 ноября 2013

Чтобы увидеть повторяющиеся значения:

with MYCTE  as (
    select row_number() over ( partition by name  order by name) rown, *
    from tmptest  
    ) 
select * from MYCTE where rown <=1
3 голосов
/ 14 декабря 2010

Если вы используете SQL Server 2005 или более позднюю версию (а теги для вашего вопроса указывают на SQL Server 2008), вы можете использовать функции ранжирования для возврата дубликатов записей после первой, если использование объединений менее желательно или нецелесообразно для некоторых причина. Следующий пример показывает это в действии, где он также работает с нулевыми значениями в исследованных столбцах.

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

Обратите внимание после запуска этого примера, что первая запись из каждой "группы" исключена и что записи с нулевыми значениями обрабатываются правильно.

Если у вас нет доступного столбца для упорядочения записей в группе, вы можете использовать столбцы с разделением по столбцам в качестве столбцов с упорядочением по.

1 голос
/ 19 ноября 2016
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 голосов
/ 17 февраля 2019

Попробуйте этот запрос, чтобы иметь счетчик sepratley для каждого оператора 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...