2009-10-12 7 views
1

-je supprimer des enregistrements en double demi dans le tableau suivantSuppression de requêtes SQL en double aide

ID  PID  SCORE 
1  1  50 
2  33  20 
3  1  90 
4  5  55 
5  7  11 
6  22  34 

Pour tout existe Dupliquons PID que je veux supprimer l'enregistrement de score le plus bas. Dans l'exemple ci-dessus, l'ID 1 serait supprimé. J'essaie de trouver une façon de le faire sans utiliser de boucles, mais j'ai vraiment du mal.

Toute aide serait appréciée.

Merci

Répondre

1
DELETE t.* 
    FROM Table1 t 
    JOIN (SELECT pid, MIN(score) minScore, MAX(id) maxId 
      FROM Table1 
     GROUP BY pid) t1 
    ON t.pid = t1.pid 
    AND t.score = t1.minScore 
    AND t.id < t1.maxId 
0
WITH q AS 
     (
     SELECT *, ROW_NUMBER() OVER (PARTITION BY pid ORDER BY score) AS rn 
     FROM mytable 
     ) 
DELETE 
FROM q 
WHERE rn = 1 

Pour laisser les résultats qui ont pas de doublons:

WITH q AS 
     (
     SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY pid ORDER BY score) AS rn, 
       COUNT(*) OVER (PARTITION BY pid) AS cnt 
     FROM mytable 
     ) 
DELETE 
FROM q 
WHERE rn = 1 
     AND cnt > 1 
+3

Comment cela fonctionne il ne regarde même pas le score? – Mark

+0

Est-ce que cela ne supprimerait pas non plus les enregistrements qui n'ont pas de doublon? – Gavin

+0

ne devriez-vous pas partitionner par pid, classer par score et supprimer où numéro de ligne = 2? – Preets

-1

je ne peux pas voir votre requête, donc j'ai pris cet exemple ...

SELECT 
    PID, 
    MAX(Score) 
FROM 
    tblTable 
GROUP BY 
    PID 
+0

Qui sélectionne ceux que l'OP ne veut pas supprimer les autres – Mark

0

essayez ceci ..

declare @tt table(id int, pid int,score int) 
    insert into @tt 
    select 1,1,50 union all 
    select 2,33,50 union all 
    select 8,33,80 union all 
    select 3,1,90 union all 
    select 4,5,50 union all 
    select 5,5,10 union all 
    select 6,6,10 union all 
    select 7,6,50 
    --------- 
    delete from @tt where id in (
    select t1.id from @tt t1 inner join 
    (
     select MIN(score) tScore,pid tPid from @tt where pid in 
     (select pid from @tt group by pid having count (pid) > 1) group by pid 
    ) t2 on t1.pid=t2.tPid and t1.score=t2.tScore) 

    select * from @tt