5

一括挿入スクリプトを間違えたため、colXが異なる「重複した」行ができました。この重複する行を削除する必要がありますが、その方法がわかりません。より正確に言えば、私はこれを持っています:

 col1 | col2 | col3 | colX      
----+----------------------
  0   |  1   |  2   |  a
  0   |  1   |  2   |  b
  0   |  1   |  2   |  c
  0   |  1   |  2   |  a
  3   |  4   |  5   |  x
  3   |  4   |  5   |  y
  3   |  4   |  5   |  x
  3   |  4   |  5   |  z

そして、それぞれの最初の出現を保持したい(row、colX):

 col1 | col2 | col3 | colX      
----+----------------------
  0   |  1   |  2   |  a
  3   |  4   |  5   |  x

返信ありがとうございます:)

4

7 に答える 7

10

SQL ServerのCTEを使用して最も簡単なアプローチを試してください:http ://www.sqlfiddle.com/#!3 / 2d386 / 2

データ:

CREATE TABLE tbl
    ([col1] int, [col2] int, [col3] int, [colX] varchar(1));

INSERT INTO tbl
    ([col1], [col2], [col3], [colX])
VALUES
    (0, 1, 2, 'a'),
    (0, 1, 2, 'b'),
    (0, 1, 2, 'c'),
    (0, 1, 2, 'a'),
    (3, 4, 5, 'x'),
    (3, 4, 5, 'y'),
    (3, 4, 5, 'x'),
    (3, 4, 5, 'z');

解決:

select * from tbl;

with a as
(
  select row_number() over(partition by col1 order by col2, col3, colX) as rn 
  from tbl   
)
delete from a where rn > 1;

select * from tbl;

出力:

| COL1 | COL2 | COL3 | COLX |
-----------------------------
|    0 |    1 |    2 |    a |
|    0 |    1 |    2 |    b |
|    0 |    1 |    2 |    c |
|    0 |    1 |    2 |    a |
|    3 |    4 |    5 |    x |
|    3 |    4 |    5 |    y |
|    3 |    4 |    5 |    x |
|    3 |    4 |    5 |    z |


| COL1 | COL2 | COL3 | COLX |
-----------------------------
|    0 |    1 |    2 |    a |
|    3 |    4 |    5 |    x |

またはおそらくこれ:http ://www.sqlfiddle.com/#!3 / af826 / 1

データ:

CREATE TABLE tbl
    ([col1] int, [col2] int, [col3] int, [colX] varchar(1));

INSERT INTO tbl
    ([col1], [col2], [col3], [colX])
VALUES
    (0, 1, 2, 'a'),
    (0, 1, 2, 'b'),
    (0, 1, 2, 'c'),
    (0, 1, 2, 'a'),
    (0, 1, 3, 'a'),
    (3, 4, 5, 'x'),
    (3, 4, 5, 'y'),
    (3, 4, 5, 'x'),
    (3, 4, 5, 'z');

解決:

select * from tbl;


with a as
(
    select row_number() over(partition by col1, col2, col3 order by colX) as rn 
    from tbl   
)
delete from a where rn > 1;

select * from tbl;

出力:

| COL1 | COL2 | COL3 | COLX |
-----------------------------
|    0 |    1 |    2 |    a |
|    0 |    1 |    2 |    b |
|    0 |    1 |    2 |    c |
|    0 |    1 |    2 |    a |
|    0 |    1 |    3 |    a |
|    3 |    4 |    5 |    x |
|    3 |    4 |    5 |    y |
|    3 |    4 |    5 |    x |
|    3 |    4 |    5 |    z |

| COL1 | COL2 | COL3 | COLX |
-----------------------------
|    0 |    1 |    2 |    a |
|    0 |    1 |    3 |    a |
|    3 |    4 |    5 |    x |
于 2012-06-21T04:08:41.617 に答える
2

colXの最小値を維持するだけで問題がない場合は、次のように実行できます。

delete t from t inner join 
    (select  min(colx) mincolx, col1, col2, col3
     from t
     group by col1, col2, col3
     having count(1) > 1) as duplicates
   on (duplicates.col1 = t.col1
   and duplicates.col2 = t.col2
   and duplicates.col3 = t.col3
   and duplicates.mincolx <> t.colx)

問題は、4つの列すべてが同じである行がまだあることです。これらを取り除くには、最初のクエリを実行した後、一時テーブルを使用する必要があります。

SELECT distinct col1, col2, col3, colx 
INTO temp
  FROM (SELECT col1, col2, col3
         from t 
         group by col1, col2, col3
         having count(1) > 1) subq;

DELETE from t where exists 
   (select 1 from temp 
     where temp.col1 = t.col1 
       and temp.col2 = t.col2 
       and temp.col3 = t.col3);

これがSQLFiddleの例です。

于 2012-06-21T03:25:51.267 に答える
2

重複が多い場合は、CTEを使用し、重複していないすべてのレコードを別のテーブルで読み取ることをお勧めします。ただし、フォローする推奨の投稿があります:MSDN

于 2012-06-21T03:10:01.870 に答える
1

colXが一意であると仮定すると(「異なるcolX」と言ったとしても、この例ではそうではありません)、以下を使用して重複を削除できます。

;with cteDuplicates as
(
    select 
        *,
        row_number() over (partition by col1, col2, col3 order by colX) as ID
    from Duplicates
)
delete D from Duplicates D
    inner join cteDuplicates C on C.colX = D.Colx
where ID > 1

(テーブルの名前が「重複」であるとしましょう)

colXが一意でない場合は、新しいuniqueidentifier列を追加し、その列に個別の値を挿入してから、colXの代わりにその列に結合して上記のコードを使用します。

于 2012-06-21T03:16:50.377 に答える
0

私はあなたが使用していると思いますSQL Server 2005/2008.

SELECT col1,
       col2,
       col3,
       colx
FROM
  (SELECT *,
          row_number() OVER (PARTITION BY col1,col2,col3
                             ORDER BY colx) AS r
   FROM table_name) a
WHERE r = 1;
于 2012-06-21T04:29:39.937 に答える
0

最も簡単な解決策は次のようになります。Oracleデータベース上に重複する行を持つテーブルemp_dept(empid、deptid)があるとします。

  delete from emp_dept where exists ( select * from emp_dept i where i.empid = emp_dept.empid and i.deptid = emp_dept.deptid and i.rowid < emp_dept.rowid ) 

SQLサーバーまたは行IDのような機能をサポートしていないデータベースでは、各行を識別するためだけにID列を追加する必要があります。テーブルにIDとしてnidを追加したと言います

alter table emp_dept add nid int identity(1,1) -- to add identity column

重複を削除するクエリは、次のように記述できます。

  delete from emp_dept where exists ( select * from emp_dept i where i.empid = emp_dept.empid and i.deptid = emp_dept.deptid and i.nid< emp_dept.nid ) 

ここでの概念は、コア値が類似しているがROWIDまたはIDが小さい他の行が存在するすべての行を削除することです。したがって、重複する行が存在する場合、より高い行IDまたはIDを持つ行が削除されます。行の場合、重複がないため、下位の行IDの検索に失敗するため、削除されません。

于 2013-06-11T06:19:20.677 に答える
0

自己責任でこのコードを試してください

Delete from Table_name
WHERE Table_name.%%physloc%%
      NOT IN (SELECT MAX(b.%%physloc%%)
              FROM   Table_name b
              group by Col_1,Col_2)

row_number()を使用する2番目のメソッドこれは安全なメソッドです

WITH CTE_Dup AS
(

 SELECT * ROW_NUMBER()OVER (PARTITIONBY SalesOrderno, ItemNo ORDER BY SalesOrderno, ItemNo)
 AS ROW_NO
 from dbo.SalesOrderDetails
)
Delete FROM CTE_Dup;
于 2014-12-08T17:55:32.633 に答える