2017-11-28 16 views
1

重複する行を含む一時テーブルがあります。一時テーブルから重複する行を削除する

DELETE FROM #Payments 
LEFT OUTER JOIN 
    (
    SELECT 
     CONVERT(uniqueidentifier, MIN(CONVERT(char(36), DocumentNo))) as RowId 
     ,[ClearingDoc] 
     , [PaymentType] 
     , [DocDate] 
    FROM #Payments 
    GROUP BY [DocumentNo], [ClearingDoc], [PaymentType], [DocDate] 
) 
as KeepRows ON #Payments.RowId = KeepRows.RowId 
WHERE KeepRows.RowId IS NULL 
; 

しかし、私はエラーIncorrect syntax near LEFTを取得しておいてください。私は、このテーブルから重複行を削除しようとしています。私はたぶんそれをあまりにも凝視しているかもしれませんが、私は間違って何をしていますか?

+0

テーブル構造を追加すると、これはずっと簡単になります。どの列が主キーですか? – Zorkolot

答えて

2

正確に何をしようとしているのかは不明です。クエリでは、group byキーの列の最小値が使用されています。

しかし、あなたは文書ごとに最新の行を維持したいならば、あなたはrow_number()を使用することができます。

with todelete as (
     select p.*, 
      row_number() over (partition by DocumentNo 
           order by DocDate desc 
           ) as seqnum 
     from #payments p 
    ) 
delete from todelete 
    where seqnum > 1; 
0

あなたが新しい一時テーブルに保持したい行を選択するために、より少ないリソースintesniveになります。

SELECT distinct [DocumentNo], [ClearingDoc], [PaymentType], [DocDate] 
    into #P2 from #Payments 

また、すべてのフィールドが一意でない場合は、GROUP BYを追加できます。

0

私は、自然な鍵とは何か、レコード間の差別化は何ですか?

これを解決するための簡単なT-SQLコーディングテストをしましょう。

以下のコードは、整数、日付、および文字を使用して簡単なテーブルを作成します。

-- Use a default db 
USE [model]; 
GO 

-- Create temp table 
CREATE TABLE #Payments 
(
DocumentNo int, 
DocDate date, 
ClearingDoc int, 
PaymentType char(1) 
); 
GO 

-- Clear table 
TRUNCATE TABLE #Payments 
GO 

-- Add data 
INSERT INTO #Payments VALUES (1, dateadd(d, -5, getdate()), 1, 'A'); 
INSERT INTO #Payments VALUES (2, dateadd(d, -4, getdate()), 1, 'B'); 
INSERT INTO #Payments VALUES (2, dateadd(d, -3, getdate()), 1, 'B'); 
INSERT INTO #Payments VALUES (1, dateadd(d, -2, getdate()), 1, 'A'); 
GO 

-- Show data 
SELECT * FROM #Payments 
GO 

このステートメントを実行すると、データは次のようになります。

自然キーは、文書番号、決済書類、支払タイプです。最も古い文書日付のレコードを探したい。

enter image description here

私は古いファッション・グループを使用して句を有する共通テーブル式を使用して好きです。

次のコードは、最も古い文書日付の重複レコードを返します。 CTE/DELETE文の中

-- Find the oldest records 
SELECT DocumentNo, ClearingDoc, PaymentType, MIN(DocDate) AS OldestDate 
FROM #Payments 
GROUP BY DocumentNo, ClearingDoc, PaymentType 
HAVING COUNT(*) > 1 

enter image description here

なく、少なくとも最後に、パッケージのコード。

-- Remove duplicate data by oldest date 
; 
WITH CTE_DELETE_LIST AS 
(
SELECT 
    DocumentNo, 
    ClearingDoc, 
    PaymentType, 
    MIN(DocDate) AS OldestDate 
FROM 
    #Payments 
GROUP BY 
    DocumentNo, ClearingDoc, PaymentType 
HAVING 
    COUNT(*) > 1 
) 
DELETE 
FROM #Payments 
FROM #Payments AS P 
JOIN 
    CTE_DELETE_LIST AS C 
ON P.DocumentNo = C.DocumentNo and 
    P.ClearingDoc = C.ClearingDoc and 
    P.PaymentType = C.PaymentType and 
    P.DocDate = C.OldestDate 

これは、2つの最も古い行を削除できる表のスナップショットです。

enter image description here

関連する問題