Выберите оператор, чтобы найти дубликаты на определенных полях
Можете ли вы помочь мне с инструкциями SQL, чтобы найти дубликаты в нескольких полях?
Например, в псевдокоде:
select count(field1,field2,field3)
from table
where the combination of field1, field2, field3 occurs multiple times
и из приведенного выше заявления, если есть несколько случаев, я хотел бы выбрать каждую запись, кроме первой.
9 ответов
Чтобы получить список полей, для которых есть несколько записей, вы можете использовать..
select field1,field2,field3, count(*)
from table_name
group by field1,field2,field3
having count(*) > 1
Проверьте эту ссылку для получения дополнительной информации о том, как удалить строки.
http://support.microsoft.com/kb/139444
Редактировать: Как упоминали другие пользователи, должен быть критерий для определения того, как вы определяете "первые строки", прежде чем использовать подход по ссылке выше. Исходя из этого, вам нужно будет использовать порядок заказов и подзапрос, если это необходимо. Если вы можете опубликовать пример данных, это действительно поможет.
Вы упоминаете "первый", поэтому я предполагаю, что у вас есть какой-то порядок в ваших данных. Давайте предположим, что ваши данные упорядочены по какому-то полю 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)
Это забавное решение с 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
Чтобы увидеть повторяющиеся значения
with MYCTE as (
select row_number() over ( partition by name order by name) rown, * from tmptest
)
select * from MYCTE where rown <=1
Если вы используете 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
Обратите внимание после запуска этого примера, что первая запись из каждой "группы" исключена и что записи с нулевыми значениями обрабатываются правильно.
Если у вас нет доступного столбца для упорядочения записей в группе, вы можете использовать столбцы с разделением по столбцам в качестве столбцов с упорядочением по.
Попробуйте этот запрос, чтобы иметь счетчик 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
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
Попробуйте этот запрос, чтобы найти повторяющиеся записи в нескольких полях
SELECT a.column1, a.column2
FROM dbo.a a
JOIN (SELECT column1,
column2, count(*) as countC
FROM dbo.a
GROUP BY column4, column5
HAVING count(*) > 1 ) b
ON a.column1 = b.column1
AND a.column2 = b.column2
Вы также можете попробовать этот запрос для подсчета
distinct()
колонка и
order by
с желаемой колонкой:
select field1, field2, field3, count(distinct (field2))
from table_name
group by field1, field2, field3
having count(field2) > 1
order by field2;