Найти дубликаты записей в таблице с помощью SQL Server - PullRequest
41 голосов
/ 24 марта 2012

Я проверяю таблицу с данными об уровне транзакций сайта электронной коммерции и нахожу точные ошибки.

Я хочу, чтобы вы помогли найти повторяющиеся записи в таблице из 50 столбцов на SQL Server.

Предположим, мои данные:

OrderNo shoppername amountpayed city Item       
1       Sam         10          A    Iphone
1       Sam         10          A    Iphone--->>Duplication to be detected
1       Sam         5           A    Ipod
2       John        20          B    Macbook
3       John        25          B    Macbookair
4       Jack        5           A    Ipod

Предположим, я использую следующий запрос:

Select shoppername,count(*) as cnt
from dbo.sales
having count(*) > 1
group by shoppername

вернет мне

Sam  2
John 2

Но я не хочу находить дубликаты чуть более 1 или 2 столбцов. Я хочу найти дубликат по всем столбцам в моих данных. Я хочу результат как:

1       Sam         10          A    Iphone

Ответы [ 13 ]

64 голосов
/ 24 марта 2012
with x as   (select  *,rn = row_number()
            over(PARTITION BY OrderNo,item  order by OrderNo)
            from    #temp1)

select * from x
where rn > 1

Вы можете удалить дубликаты, заменив оператор выбора на

delete x where rn > 1
41 голосов
/ 24 марта 2012
SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as cnt
FROM dbo.sales
GROUP BY OrderNo, shoppername, amountPayed, city, item
HAVING COUNT(*) > 1
4 голосов
/ 17 декабря 2012
SQL> SELECT JOB,COUNT(JOB) FROM EMP GROUP BY JOB;

JOB       COUNT(JOB)
--------- ----------
ANALYST            2
CLERK              4
MANAGER            3
PRESIDENT          1
SALESMAN           4
3 голосов
/ 28 ноября 2015

Чтобы получить список из нескольких записей, используйте следующую команду

select field1,field2,field3, count(*)
  from table_name
  group by field1,field2,field3
  having count(*) > 1
3 голосов
/ 24 марта 2012

Просто добавьте все поля в запрос и не забудьте также добавить их в Group By.

Select shoppername, a, b, amountpayed, item, count(*) as cnt
from dbo.sales
group by shoppername, a, b, amountpayed, item
having count(*) > 1
1 голос
/ 24 марта 2012

Попробуйте вместо этого

SELECT MAX(shoppername), COUNT(*) AS cnt
FROM dbo.sales
GROUP BY CHECKSUM(*)
HAVING COUNT(*) > 1

Сначала прочитайте о функции CHECKSUM , так как возможны дубликаты.

0 голосов
/ 22 апреля 2018

Вы можете использовать следующие методы, чтобы найти вывод

 with Ctec AS
 (
select *,Row_number() over(partition by name order by Name)Rnk
 from Table_A
)
select  Name from ctec
where rnk>1

select name from Table_A
 group by name
 having count(*)>1
0 голосов
/ 13 января 2017

Попробуйте это

with T1 AS
(
SELECT LASTNAME, COUNT(1) AS 'COUNT' FROM Employees GROUP BY LastName HAVING  COUNT(1) > 1
)
SELECT E.*,T1.[COUNT] FROM Employees E INNER JOIN T1 ON T1.LastName = E.LastName
0 голосов
/ 02 ноября 2016

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

Тогда мы подходим к самому вопросу.Исходя из вашей таблицы, лучший способ показать повторяющиеся значения - использовать предложения count(*) и Group by.Запрос будет выглядеть следующим образом:

SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as RepeatTimes FROM dbo.sales GROUP BY OrderNo, shoppername, amountPayed, city, item HAVING COUNT(*) > 1

Причина в том, что все столбцы в вашей таблице однозначно идентифицируют каждую запись, что означает, что записи будут считаться дублирующими только тогда, когда все значения изкаждый столбец точно такой же, также вы хотите показать все поля для повторяющихся записей, поэтому group by не пропустит ни один столбец, в противном случае да, потому что вы можете только select столбцы, которые участвуют в предложении 'group by'.

Теперь я хотел бы привести любой пример для With...Row_Number()Over(...), который использует табличное выражение вместе с функцией Row_Number.

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

OrderNo shoppername amountpayed city Item Shipping Date<br> 1 Sam 10 A Iphone 2016-01-01 1 Sam 10 A Iphone 2016-02-02 1 Sam 5 A Ipod 2016-03-03 2 John 20 B Macbook 2016-04-04 3 John 25 B Macbookair 2016-05-05 4 Jack 5 A Ipod 2016-06-06

Обратите внимание, что строка № 2 не является дубликатом, если вы по-прежнему принимаете все столбцы за единицу.Но что, если вы хотите рассматривать их как дубликаты в этом случае?Вы должны использовать With...Row_Number()Over(...), и запрос будет выглядеть следующим образом:

WITH TABLEEXPRESSION AS (SELECT *,ROW_NUMBER() OVER (PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier) --if you consider the one with late shipping date as the duplicate FROM dbo.sales) SELECT * FROM TABLEEXPRESSION WHERE Identifier !=1 --or use '>1'

Приведенный выше запрос даст результат вместе с датой доставки, например:

OrderNo shoppername amountpayed city Item Shipping Date Identifier 1 Sam 10 A Iphone 2016-02-02 2

Обратите внимание, что этот вариант отличается от того, который указан в 2016-01-01, и причина, по которой 2016-02-02 был отфильтрован, PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier, а Дата отгрузки НЕ является одной изстолбец, о котором нужно позаботиться о дубликатах записей, что означает, что столбец с 2016-02-02 все еще может быть идеальным результатом для вашего вопроса.

Теперь немного суммируйте его, используя count(*) и *Предложение 1039 * вместе - это лучший выбор, когда вы хотите показать все столбцы из предложения Group by как результат, в противном случае вы пропустите столбцы, которые не участвуют в group by.

While For With...Row_Number()Over(...) подходит для каждого сценария, в котором вы хотите найти повторяющиеся записи, однако, написать запрос немного сложнее и немного сложнее, чем предыдущий.

Если ваша цельявляется чтобы удалить дубликаты записей из таблицы, вы должны использовать более позднюю WITH...ROW_NUMBER()OVER(...)...DELETE FROM...WHERE одну.

Надеюсь, это поможет!

0 голосов
/ 21 октября 2016

Следующий код работает:

SELECT abnno, COUNT(abnno)
FROM tbl_Name
GROUP BY abnno
HAVING ( COUNT(abnno) > 1 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...