0

テーブルから重複するレコードを削除し、最新のレコード(日付による)を残したいと思います。以下の例では、最初のレコードが削除されます(hdate = 2012-07-01、id = 16)。

SQLServer2008の使用

ありがとう

hdate      id           secId       pricesource          price         
---------- ------------ ----------- -------------------- --------------
2012-07-01 16           126         DFLT                 NULL          
2012-07-02 16           126         DFLT                 NULL          
2012-07-01 CAD          20          DFLT                 1             
2012-07-01 TWD          99          DFLT                 1   
4

3 に答える 3

2

Sql-Server 2005以降ROW_NUMBERでは、適切なOVER:でCTE使用できます。

WITH CTE AS
(
  SELECT hdate, id, secId, pricesource, price,
  ROW_NUMBER() OVER (PARTITION BY id, secId, pricesource, price ORDER BY hdate DESC) AS RN
  FROM dbo.TableName t
)
DELETE FROM CTE WHERE RN > 1

これがSQLフィドルのデモです

于 2012-11-16T15:31:39.670 に答える
0

RDBMSがCTEをサポートしていない場合、またはCTEから削除できる場合(使用しているものをリストしていないため)、他のすべてのバージョンは次のとおりです。

DELETE FROM TableName as a
WHERE EXISTS (SELECT '1'
              FROM TableName b
              WHERE b.id = a.id  -- Plus all other 'duplicate' columns
                    AND b.hdate > a.hdate);

(そして、Timの修正されたFiddleデモ-何らかの理由でこれはSQL Serverでは機能しませんが)。

于 2012-11-16T17:23:46.687 に答える
0

これはTimのソリューションほどエレガントではありませんが、CTEを必要としません。また、列内のnullを同等に処理します。

DELETE
FROM MyTable m1
WHERE EXISTS (
    SELECT 1
    FROM MyTable m2
    WHERE 
        (m2.id = m1.id OR (m2.id IS NULL AND m1.id IS NULL))
    AND (m2.secId = m1.secId OR (m2.secId IS NULL AND m1.secId IS NULL))
    AND (m2.pricesource = m1.pricesource OR (m2.pricesource IS NULL AND m1.pricesource IS NULL))
    AND (m2.price = m1.price  OR (m2.price IS NULL AND m1.price IS NULL))
    AND m2.hdate > m1.hdate
);
于 2012-11-16T17:35:38.850 に答える