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 回答