どうすればいいですかdelete duplicate rows
unique row id
が存在しない場合
私のテーブルは
col1 col2 col3 col4 col5 col6 col7
john 1 1 1 1 1 1
john 1 1 1 1 1 1
sally 2 2 2 2 2 2
sally 2 2 2 2 2 2
重複削除の後、次のものを残したままにします。
john 1 1 1 1 1 1
sally 2 2 2 2 2 2
私はいくつかのクエリを試してみましたが、私は望ましい結果が得られないので、それらは行IDに依存すると思います。例えば:
DELETE FROM table WHERE col1 IN (
SELECT id FROM table GROUP BY id HAVING ( COUNT(col1) > 1 )
)
CTEとROW_NUMBER
を組み合わせると、どの行が削除(または更新)されているかを確認できるので、DELETE FROM CTE...
をSELECT * FROM CTE
に変更するだけです。
WITH CTE AS(
SELECT [col1], [col2], [col3], [col4], [col5], [col6], [col7],
RN = ROW_NUMBER()OVER(PARTITION BY col1 ORDER BY col1)
FROM dbo.Table1
)
DELETE FROM CTE WHERE RN > 1
DEMO (結果は異なります。私はそれがあなたの側のタイプミスが原因だと思います)
COL1 COL2 COL3 COL4 COL5 COL6 COL7
john 1 1 1 1 1 1
sally 2 2 2 2 2 2
この例では、col1
のため、単一の列PARTITION BY col1
で重複を判断します。複数の列を含める場合は、それらをPARTITION BY
に追加するだけです。
ROW_NUMBER()OVER(PARTITION BY Col1, Col2, ... ORDER BY OrderColumn)
私はSQL Serverのテーブルから重複した行を削除するためのCTEを好むでしょう
この記事に従うことを強くお勧めします:: http://codaffection.com/sql-server-article/delete-duplicate-rows-in-sql-server/
オリジナルのままに
WITH CTE AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY col1,col2,col3 ORDER BY col1,col2,col3) AS RN
FROM MyTable
)
DELETE FROM CTE WHERE RN<>1
元のままにせずに
WITH CTE AS
(SELECT *,R=RANK() OVER (ORDER BY col1,col2,col3)
FROM MyTable)
DELETE CTE
WHERE R IN (SELECT R FROM CTE GROUP BY R HAVING COUNT(*)>1)
CTE
とROW_NUMBER()
を使わなくても、group byとMAX
関数を使ってレコードを削除できます。
DELETE
FROM MyDuplicateTable
WHERE ID NOT IN
(
SELECT MAX(ID)
FROM MyDuplicateTable
GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3)
DELETE from search
where id not in (
select min(id) from search
group by url
having count(*)=1
union
SELECT min(id) FROM search
group by url
having count(*) > 1
)
Microsoftは、重複を削除する方法についてきちんとしたガイドを持っています。チェックアウト http://support.Microsoft.com/kb/139444
簡単に言うと、削除する行が数行しかない場合に重複を削除する最も簡単な方法は次のとおりです。
SET rowcount 1;
DELETE FROM t1 WHERE myprimarykey=1;
myprimarykey は行の識別子です。
重複した行は2行しかないので、 rowcount を1に設定します。 3行複製した場合は、最初の2行を削除してテーブルt1に1行だけ残すように、 rowcount を2に設定します。
誰かに役立つことを願っています
下記の削除方法もご覧ください。
Declare @table table
(col1 varchar(10),col2 int,col3 int, col4 int, col5 int, col6 int, col7 int)
Insert into @table values
('john',1,1,1,1,1,1),
('john',1,1,1,1,1,1),
('sally',2,2,2,2,2,2),
('sally',2,2,2,2,2,2)
@table
という名前のサンプル表を作成し、それに所定のデータをロードしました。
Delete aliasName from (
Select *,
ROW_NUMBER() over (Partition by col1,col2,col3,col4,col5,col6,col7 order by col1) as rowNumber
From @table) aliasName
Where rowNumber > 1
Select * from @table
注:Partition by
部分のすべての列を指定している場合、order by
はそれほど重要ではありません。
私は知っている、3年前に質問がされている、そして私の答えはTimが投稿したものの別のバージョンだ。
外部キーのように参照がない場合は、これを実行できます。概念実証をテストしてテストデータが複製されるとき、私はそれをたくさんします。
SELECT DISTINCT [col1]、[col2]、[col3]、[col4]、[col5]、[col6]、[col7]
INTO [newTable]
;
オブジェクトエクスプローラに移動し、古いテーブルを削除します。
新しいテーブルの名前を古いテーブルの名前に変更します。
上記の提案された解決策を試した後に、それは小さな中型テーブルのために働く。非常に大きなテーブルに対しては、その解決策を提案できます。繰り返し実行されるためです。
LargeSourceTable
のすべての依存関係ビューを削除するsp_rename 'LargeSourceTable', 'LargeSourceTable_Temp'; GO
LargeSourceTable
を作成しますが、今度は重複を定義するすべての列を含む主キーを追加しますadd WITH (IGNORE_DUP_KEY = ON)
例えば:
CREATE TABLE [dbo].[LargeSourceTable] ( ID int IDENTITY(1,1), [CreateDate] DATETIME CONSTRAINT [DF_LargeSourceTable_CreateDate] DEFAULT (getdate()) NOT NULL, [Column1] CHAR (36) NOT NULL, [Column2] NVARCHAR (100) NOT NULL, [Column3] CHAR (36) NOT NULL, PRIMARY KEY (Column1, Column2) WITH (IGNORE_DUP_KEY = ON) ); GO
新しく作成したテーブル用に最初にドロップしたビューをもう一度作成します。
では、次のSQLスクリプトを実行すると、1ページに1,000,000行の結果が表示されます。1ページに表示される行数を変更して、結果をより頻繁に表示できます。
私はIDENTITY_INSERT
をonとoffに設定したことに注意してください
SET IDENTITY_INSERT LargeSourceTable ON DECLARE @PageNumber AS INT, @RowspPage AS INT DECLARE @TotalRows AS INT declare @dt varchar(19) SET @PageNumber = 0 SET @RowspPage = 1000000
select @TotalRows = count (*) from LargeSourceTable_TEMP
While ((@PageNumber - 1) * @RowspPage < @TotalRows )
Begin
begin transaction tran_inner
; with cte as
(
SELECT * FROM LargeSourceTable_TEMP ORDER BY ID
OFFSET ((@PageNumber) * @RowspPage) ROWS
FETCH NEXT @RowspPage ROWS ONLY
)
INSERT INTO LargeSourceTable
(
ID
,[CreateDate]
,[Column1]
,[Column2]
,[Column3]
)
select
ID
,[CreateDate]
,[Column1]
,[Column2]
,[Column3]
from cte
commit transaction tran_inner
PRINT 'Page: ' + convert(varchar(10), @PageNumber)
PRINT 'Transfered: ' + convert(varchar(20), @PageNumber * @RowspPage)
PRINT 'Of: ' + convert(varchar(20), @TotalRows)
SELECT @dt = convert(varchar(19), getdate(), 121)
RAISERROR('Inserted on: %s', 0, 1, @dt) WITH NOWAIT
SET @PageNumber = @PageNumber + 1
End
SET IDENTITY_INSERT LargeSourceTable OFF
-- this query will keep only one instance of a duplicate record.
;WITH cte
AS (SELECT ROW_NUMBER() OVER (PARTITION BY col1, col2, col3-- based on what? --can be multiple columns
ORDER BY ( SELECT 0)) RN
FROM Mytable)
delete FROM cte
WHERE RN > 1
SELECT DISTINCT * FROM TABLE;
これにより、重複する行がすべて削除され、個別の値(行)だけが表示されます。
重複レコードをフィールドに従ってグループ化してから、レコードの1つを保持して残りを削除する必要があります。例えば:
DELETE prg.Person WHERE Id IN (
SELECT dublicateRow.Id FROM
(
select MIN(Id) MinId, NationalCode
from prg.Person group by NationalCode having count(NationalCode ) > 1
) GroupSelect
JOIN prg.Person dublicateRow ON dublicateRow.NationalCode = GroupSelect.NationalCode
WHERE dublicateRow.Id <> GroupSelect.MinId)
あなたが一時的にテーブルに列を追加する能力を持っているなら、これは私のために働いた解決策でした:
ALTER TABLE dbo.DUPPEDTABLE ADD RowID INT NOT NULL IDENTITY(1,1)
次にMINとGROUP BYの組み合わせを使用してDELETEを実行します。
DELETE b
FROM dbo.DUPPEDTABLE b
WHERE b.RowID NOT IN (
SELECT MIN(RowID) AS RowID
FROM dbo.DUPPEDTABLE a WITH (NOLOCK)
GROUP BY a.ITEM_NUMBER,
a.CHARACTERISTIC,
a.INTVALUE,
a.FLOATVALUE,
a.STRINGVALUE
);
DELETEが正しく実行されたことを確認します。
SELECT a.ITEM_NUMBER,
a.CHARACTERISTIC,
a.INTVALUE,
a.FLOATVALUE,
a.STRINGVALUE, COUNT(*)--MIN(RowID) AS RowID
FROM dbo.DUPPEDTABLE a WITH (NOLOCK)
GROUP BY a.ITEM_NUMBER,
a.CHARACTERISTIC,
a.INTVALUE,
a.FLOATVALUE,
a.STRINGVALUE
ORDER BY COUNT(*) DESC
結果には、1より大きいカウントを持つ行が含まれていないはずです。最後に、rowid列を削除します。
ALTER TABLE dbo.DUPPEDTABLE DROP COLUMN RowID;
重複を削除するという考えには、
ステップバイステップ
with myCTE
as
(
select productName,ROW_NUMBER() over(PARTITION BY productName order by slno) as Duplicate from productDetails
)
Delete from myCTE where Duplicate>1
DECLARE @TB TABLE(NAME VARCHAR(100));
INSERT INTO @TB VALUES ('Red'),('Red'),('Green'),('Blue'),('White'),('White')
--**Delete by Rank**
;WITH CTE AS(SELECT NAME,DENSE_RANK() OVER (PARTITION BY NAME ORDER BY NEWID()) ID FROM @TB)
DELETE FROM CTE WHERE ID>1
SELECT NAME FROM @TB;
--**Delete by Row Number**
;WITH CTE AS(SELECT NAME,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY NAME) ID FROM @TB)
DELETE FROM CTE WHERE ID>1;
SELECT NAME FROM @TB;
巨大な(数百万件のレコード)テーブルから重複を削除するには、長い時間がかかる場合があります。削除するのではなく、選択した行の一時テーブルに一括挿入することをお勧めします。
--REWRITING YOUR CODE(TAKE NOTE OF THE 3RD LINE) WITH CTE AS(SELECT NAME,ROW_NUMBER()
OVER (PARTITION BY NAME ORDER BY NAME) ID FROM @TB) SELECT * INTO #unique_records FROM
CTE WHERE ID =1;
うわー、私はすべてのこれらの答えを用意することによってとても愚かだと感じます、彼らはすべてのCTEと臨時雇用者テーブルなどに関する専門家の答えのようです。
そしてそれを動かすために私がしたのはMAXを使ってID列を単純に集約することだけでした。
DELETE FROM table WHERE col1 IN (
SELECT MAX(id) FROM table GROUP BY id HAVING ( COUNT(col1) > 1 )
)
注:重複を削除するには、一度に1セットの重複行しか削除されないため、複数回実行する必要があります。
SQLサーバーでは多くの方法で実行できます。最も簡単な方法は、重複行テーブルから新しい一時テーブルに個別の行を挿入することです。次に、重複行テーブルからすべてのデータを削除し、次に示すように、重複のない一時テーブルからすべてのデータを挿入します。
select distinct * into #tmp From table
delete from table
insert into table
select * from #tmp drop table #tmp
select * from table
共通テーブル式(CTE)を使用して重複行を削除する
With CTE_Duplicates as
(id、nameを選択し、row_number()over(idによるパーティション、idによる名前の順序、nameによるテーブルのrowname)rownumber!= 1のCTE_Duplicatesから削除します
1ステップで情報を失うことなく重複行を削除する別の方法は、次のようなものです。
delete from dublicated_table t1 (nolock)
join (
select t2.dublicated_field
, min(len(t2.field_kept)) as min_field_kept
from dublicated_table t2 (nolock)
group by t2.dublicated_field having COUNT(*)>1
) t3
on t1.dublicated_field=t3.dublicated_field
and len(t1.field_kept)=t3.min_field_kept