web-dev-qa-db-ja.com

SQL Serverで重複行を見つける

組織のSQL Serverデータベースがあり、重複行が多数あります。 selectステートメントを実行して、これらすべてと複製の量を取得するだけでなく、各組織に関連付けられているIDも返します。

のような文:

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

のようなものを返します

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

しかし、私も彼らのIDをつかみたいです。これを行う方法はありますか?たぶん

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

その理由は、これらの組織にリンクしているユーザーの別のテーブルもあり、それらを統合したいということです(したがって、ユーザーが重複組織の代わりに同じ組織にリンクするように、重複を削除します)。しかし、私は何もしないように手動で参加したいのですが、それでも私はユーザーのリストを調べることができるようにすべての重複組織のIDを返すステートメントが必要になるでしょう。

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

次のクエリを実行してmax(id)と重複している行を見つけ、それらの行を削除できます。

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

しかし、このクエリを数回実行する必要があります。

88
Aykut Akıncı

あなたはこれのようにそれをすることができます:

SELECT
    o.id, o.orgName, d.intCount
FROM (
     SELECT orgName, COUNT(*) as intCount
     FROM organizations
     GROUP BY orgName
     HAVING COUNT(*) > 1
) AS d
    INNER JOIN organizations o ON o.orgName = d.orgName

削除可能なレコードのみを返す(それぞれ1つずつ)場合は、次のようにします。

SELECT
    id, orgName
FROM (
     SELECT 
         orgName, id,
         ROW_NUMBER() OVER (PARTITION BY orgName ORDER BY id) AS intRow
     FROM organizations
) AS d
WHERE intRow != 1

編集:SQL Server 2000にはROW_NUMBER()関数はありません。代わりに、次のものを使用できます。

SELECT
    o.id, o.orgName, d.intCount
FROM (
     SELECT orgName, COUNT(*) as intCount, MIN(id) AS minId
     FROM organizations
     GROUP BY orgName
     HAVING COUNT(*) > 1
) AS d
    INNER JOIN organizations o ON o.orgName = d.orgName
WHERE d.minId != o.id
31
Paul

正しいとマークされた解決策は私にはうまくいきませんでした、しかし私はちょうどうまくいったこの答えを見つけました: MySqlの重複行のリストを取得します

SELECT n1.* 
FROM myTable n1
INNER JOIN myTable n2 
ON n2.repeatedCol = n1.repeatedCol
WHERE n1.id <> n2.id
9
ecairol

あなたはこれを試すことができます、それはあなたに最適です

 WITH CTE AS
    (
    SELECT *,RN=ROW_NUMBER() OVER (PARTITION BY orgName ORDER BY orgName DESC) FROM organizations 
    )
    select * from CTE where RN>1
    go
8
code save
select * from [Employees]

重複したレコードを見つけるために1)CTEを使う

with mycte
as
(
select Name,EmailId,ROW_NUMBER() over(partition by Name,EmailId order by id) as Duplicate from [Employees]
)
select * from mycte

2)GroupByを使って

select Name,EmailId,COUNT(name) as Duplicate from  [Employees] group by Name,EmailId 
4
Debendra Dash

重複を削除したい場合は、

WITH CTE AS(
   SELECT orgName,id,
       RN = ROW_NUMBER()OVER(PARTITION BY orgName ORDER BY Id)
   FROM organizations
)
DELETE FROM CTE WHERE RN > 1
4
akd
Select * from (Select orgName,id,
ROW_NUMBER() OVER(Partition By OrgName ORDER by id DESC) Rownum
From organizations )tbl Where Rownum>1

そのため、rowum> 1のレコードは、テーブル内の重複レコードになります。最初のグループをレコードで「分割」してから、連番を付けて連番にします。そのため、rownum> 1が重複レコードになり、それ自体を削除することができます。

3
Mike Clark
select column_name, count(column_name)
from table_name
group by column_name
having count (column_name) > 1;

Src: https://stackoverflow.com/a/59242/1465252

2
iCrazybest
select a.orgName,b.duplicate, a.id
from organizations a
inner join (
    SELECT orgName, COUNT(*) AS duplicate
    FROM organizations
    GROUP BY orgName
    HAVING COUNT(*) > 1
) b on o.orgName = oc.orgName
group by a.orgName,a.id
2
user5336758
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
1
Jordão

Select 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

テーブル 'Student'に2つの列があるとします。

  • 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
Usman Yaqoob

テーブル内の重複レコードを取得するためのより良いオプションを得ました

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

上記のクエリの結果は、一意の学生IDと重複する発生者の数を持つすべての重複する名前を示しています

SQLの結果を見るにはここをクリックしてください

0
SoftIdea
 /*To get duplicate data in table */

 SELECT COUNT(EmpCode),EmpCode FROM tbl_Employees WHERE Status=1 
  GROUP BY EmpCode HAVING COUNT(EmpCode) > 1
0
JIYAUL MUSTAPHA

私はあなたが私が答えの間で混合するのに必要としたものを知っていると思いますそして私は彼が望んだ解決策を得たと思います:

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を持っていることはあなたに共和国のIDと彼が求めたものであるオリジナルのIDを与えるでしょう:

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

それがまだ役立つことを願っています

0
Arthur Kielbasa