1

重複する列の値を検索して削除するクエリに取り組んでいます。現在、私はこのクエリを持っています(重複を返します):

SELECT NUIP, FECHA_REGISTRO
FROM registros_civiles_nacimiento
WHERE NUIP IN (
 SELECT NUIP
 FROM registros_civiles_nacimiento
 GROUP BY NUIP
 HAVING (COUNT(NUIP) > 1)
) order by NUIP

この作業は、次のようなテーブルを返します。

NUIP        FECHA_REGISTRO
38120100138 1975-05-30
38120100138 1977-08-31
40051800275 1980-09-24
40051800275 1999-11-29
42110700118 1972-10-26
42110700118 1982-04-22
44030700535 1982-10-19
44030700535 1993-05-05
46072300777 1991-01-17
46072300777 1979-03-30

問題は、列の値が重複している行を削除する必要があることです。ただし、たとえば、指定された結果について、必要なクエリが実行されたら、これは保持する必要がある結果のリストです。

NUIP        FECHA_REGISTRO
38120100138 1977-08-31
40051800275 1999-11-29
42110700118 1982-04-22
44030700535 1993-05-05
46072300777 1991-01-17

プレーンSQLを使用してこれを行うにはどうすればよいですか?

4

3 に答える 3

1
--PULL YOUR SELECT OF RECS WITH DUPES INTO A TEMP TABLE 
--(OR CREATE A NEW TABLE SO THAT YOU CAN KEEP THEM AROUND FOR LATER IN CASE)
SELECT   NUIP,FECHA_REGISTRO
INTO #NUIP 
FROM     SO_NUIP
WHERE NUIP IN (
SELECT NUIP
 FROM SO_NUIP
 GROUP BY NUIP
 HAVING (COUNT(NUIP) > 1)
)

--CREATE FLAG FOR DETERMINIG DUPES
ALTER TABLE #NUIP ADD DUPLICATETOREMOVE bit

 --USE `RANK()` TO SET FLAG
 UPDATE #NUIP
 SET DUPLICATETOREMOVE = CASE X.RANK
        WHEN  1 THEN 1
        ELSE 0 
        END
--SELECT *
FROM #NUIP A
INNER JOIN (SELECT NUIP,FECHA_REGISTRO,RANK() OVER (PARTITION BY [NUIP] ORDER BY    FECHA_REGISTRO ASC) AS RANK
FROM #NUIP) X ON X.NUIP = A.NUIP AND X.FECHA_REGISTRO = A.FECHA_REGISTRO

--HERE IS YOUR DELETE LIST
SELECT * 
FROM so_registros_civiles_nacimiento R
JOIN #NUIP N ON N.NUIP = R.NUIP AND N.FECHA_REGISTRO = R.FECHA_REGISTRO
WHERE N.DUPLICATETOREMOVE = 1

--HERE IS YOUR KEEP LIST
SELECT * 
FROM so_registros_civiles_nacimiento R
JOIN #NUIP N ON N.NUIP = R.NUIP AND N.FECHA_REGISTRO = R.FECHA_REGISTRO
WHERE N.DUPLICATETOREMOVE = 0

--ZAP THEM AND COMMIT YOUR TRANSACTION, YOU'VE STILL GOT A REC OF THE DELETEDS FOR AS LONG AS THE SCOPE OF YOUR #NUIP
BEGIN TRAN --COMMIT  --ROLLBACK
DELETE FROM so_registros_civiles_nacimiento
JOIN #NUIP N ON N.NUIP = R.NUIP AND N.FECHA_REGISTRO = R.FECHA_REGISTRO
WHERE N.DUPLICATETOREMOVE = 1
于 2012-07-10T14:58:16.287 に答える
0

これには分析関数を使用できます。

;WITH CTE AS
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY NUIP ORDER BY FECHA_REGISTRO DESC) RN
    FROM registros_civiles_nacimiento
)
DELETE FROM CTE
WHERE RN > 1;
于 2012-07-10T14:24:38.757 に答える
0
  1. RANK() を使用して、日付順の結果セットを作成します
  2. ソースから削除するには、WHERE EXISTS を使用します。

(注:重複に対してランク関数を実行すると、結果が得られるはずです。以下の表全体を参照しただけです)

このステートメントは Oracle で機能します (適切に機能する場合は、select * を delete に置き換えます。

SELECT * 
FROM registros_civiles_nacimiento ALL_ 
WHERE EXISTS 
    (SELECT * FROM    
        (SELECT * FROM 
            (SELECT  NUIP, 
                     FECHA_REGISTRO, 
                     RANK() OVER (PARTITION BY NUIP ORDER BY FECHA_REGISTRO) AS ORDER_
             FROM registros_civiles_nacimiento)
         WHERE ORDER_ = 1) OLDEST
     WHERE   ALL_.NUIP = OLDEST.NUIP
     AND   ALL_.FECHA_REGISTRO = OLDEST.FECHA_REGISTRO);
于 2012-07-10T14:52:28.947 に答える