Поиск дублирующихся строк в SQL Server - PullRequest
216 голосов
/ 21 января 2010

У меня есть база данных организаций SQL Server, и есть много повторяющихся строк. Я хочу выполнить оператор select, чтобы получить все эти данные и количество дубликатов, а также вернуть идентификаторы, связанные с каждой организацией.

утверждение типа:

SELECT     orgName, COUNT(*) AS dupes  
FROM         organizations  
GROUP BY orgName  
HAVING      (COUNT(*) > 1)

Вернет что-то вроде

orgName        | dupes  
ABC Corp       | 7  
Foo Federation | 5  
Widget Company | 2 

Но я также хотел бы получить их удостоверения личности. Есть какой-либо способ сделать это? Может быть, как

orgName        | dupeCount | id  
ABC Corp       | 1         | 34  
ABC Corp       | 2         | 5  
...  
Widget Company | 1         | 10  
Widget Company | 2         | 2  

Причина в том, что существует также отдельная таблица пользователей, которые ссылаются на эти организации, и я хотел бы объединить их (поэтому удалите дубликаты, чтобы пользователи ссылались на одну и ту же организацию, а не на двойные организации). Но я бы хотел расставить детали вручную, чтобы ничего не напортачить, но мне все равно нужен оператор, возвращающий идентификаторы всех двойных организаций, чтобы я мог просмотреть список пользователей.

Ответы [ 17 ]

1 голос
/ 07 ноября 2013

У вас есть несколько способов выбора duplicate rows.

для моих решений сначала рассмотрим эту таблицу, например

CREATE TABLE #Employee
(
ID          INT,
FIRST_NAME  NVARCHAR(100),
LAST_NAME   NVARCHAR(300)
)

INSERT INTO #Employee VALUES ( 1, 'Ardalan', 'Shahgholi' );
INSERT INTO #Employee VALUES ( 2, 'name1', 'lname1' );
INSERT INTO #Employee VALUES ( 3, 'name2', 'lname2' );
INSERT INTO #Employee VALUES ( 2, 'name1', 'lname1' );
INSERT INTO #Employee VALUES ( 3, 'name2', 'lname2' );
INSERT INTO #Employee VALUES ( 4, 'name3', 'lname3' );

Первое решение:

SELECT DISTINCT *
FROM   #Employee;

WITH #DeleteEmployee AS (
                     SELECT ROW_NUMBER()
                            OVER(PARTITION BY ID, First_Name, Last_Name ORDER BY ID) AS
                            RNUM
                     FROM   #Employee
                 )

SELECT *
FROM   #DeleteEmployee
WHERE  RNUM > 1

SELECT DISTINCT *
FROM   #Employee

Второстепенное решение: Используйте identity поле

SELECT DISTINCT *
FROM   #Employee;

ALTER TABLE #Employee ADD UNIQ_ID INT IDENTITY(1, 1)

SELECT *
FROM   #Employee
WHERE  UNIQ_ID < (
    SELECT MAX(UNIQ_ID)
    FROM   #Employee a2
    WHERE  #Employee.ID = a2.ID
           AND #Employee.FIRST_NAME = a2.FIRST_NAME
           AND #Employee.LAST_NAME = a2.LAST_NAME
)

ALTER TABLE #Employee DROP COLUMN UNIQ_ID

SELECT DISTINCT *
FROM   #Employee

и конец всего решения использовать эту команду

DROP TABLE #Employee
1 голос
/ 21 января 2010
select orgname, count(*) as dupes, id 
from organizations
where orgname in (
    select orgname
    from organizations
    group by orgname
    having (count(*) > 1)
)
group by orgname, id
0 голосов
/ 09 февраля 2018

Предположим, у нас есть таблица 'Студент' с двумя столбцами:

  • student_id int
  • student_name varchar

    Records:
    +------------+---------------------+
    | student_id | student_name        |
    +------------+---------------------+
    |        101 | usman               |
    |        101 | usman               |
    |        101 | usman               |
    |        102 | usmanyaqoob         |
    |        103 | muhammadusmanyaqoob |
    |        103 | muhammadusmanyaqoob |
    +------------+---------------------+
    

Теперь мы хотим увидеть дубликаты записей. Используйте этот запрос:

select student_name,student_id ,count(*) c from student group by student_id,student_name having c>1;

+---------------------+------------+---+
| student_name        | student_id | c |
+---------------------+------------+---+
| usman               |        101 | 3 |
| muhammadusmanyaqoob |        103 | 2 |
+---------------------+------------+---+
0 голосов
/ 22 января 2014

Попробуйте

SELECT orgName, id, count(*) as dupes
FROM organizations
GROUP BY orgName, id
HAVING count(*) > 1;
0 голосов
/ 25 июня 2018

У меня есть лучший вариант получить дубликаты записей в таблице

SELECT x.studid, y.stdname, y.dupecount
FROM student AS x INNER JOIN
(SELECT a.stdname, COUNT(*) AS dupecount
FROM student AS a INNER JOIN
studmisc AS b ON a.studid = b.studid
WHERE (a.studid LIKE '2018%') AND (b.studstatus = 4)
GROUP BY a.stdname
HAVING (COUNT(*) > 1)) AS y ON x.stdname = y.stdname INNER JOIN
studmisc AS z ON x.studid = z.studid
WHERE (x.studid LIKE '2018%') AND (z.studstatus = 4)
ORDER BY x.stdname

В результате вышеприведенного запроса отображаются все дубликаты имен с уникальными идентификаторами учеников и количеством повторяющихся вхождений

Нажмите здесь, чтобы увидеть результат sql

0 голосов
/ 26 апреля 2019
 /*To get duplicate data in table */

 SELECT COUNT(EmpCode),EmpCode FROM tbl_Employees WHERE Status=1 
  GROUP BY EmpCode HAVING COUNT(EmpCode) > 1
0 голосов
/ 01 октября 2014

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

select o.id,o.orgName, oc.dupeCount, oc.id,oc.orgName
from organizations o
inner join (
    SELECT MAX(id) as id, orgName, COUNT(*) AS dupeCount
    FROM organizations
    GROUP BY orgName
    HAVING COUNT(*) > 1
) oc on o.orgName = oc.orgName

с максимальным идентификатором даст вам идентификатор дубликата и тот из оригинала, о котором он просил:

id org name , dublicate count (missing out in this case) 
id doublicate org name , doub count (missing out again because does not help in this case)

единственная печальная вещь, которую ты получаешь в этой форме

id , name , dubid , name

надеюсь, что это все еще помогает

...