14. oktober 2005 - 13:51Der er
8 kommentarer og 1 løsning
Delete distinct?
Hej Experter.
Jeg har et lille problem som jeg håber der er nogen som kan hjælpe mig med.
Jeg har en tabel med en masse identiske poster. De har dog alle en unik primærnøgle, men ellers er mange af dem de samme. Jeg skal høre om man kan lave et SQL statement som kun sletter en af gangen af disse dubletter indtil der ikke er flere tilbage ?
I lang tid har samarbejdsbranchen fokuseret på at forbedre enhedsfunktioner – bedre kameraer, klarere lyd og smartere software. Men den virkelige forvandling handler ikke om funktioner.
Bruger du primærnøglen? Hvilken af et sæt identiske poster skal have lov at overleve?
Hvis det er ligemeget, så kan du gøre dette:
INSERT INTO Tabellen (col1, col2, col3) SELECT DISTINCT col1, col2, col3 FROM Tabellen
col1, col2, col3 erstattes med alle kolonner undtagen nøglen
Nu har du tilføjet nye poster, der er en samling af alle unikke poster der var. Så mangler du bare at slette alle gamle poster, så du har brug for at vide hvilke der er nye og gamle. Er ID'et identity? For så kan du starte med at registrere det største ID du har, og år denne INSERT har kørt slette alle der har ID <= den tidligere max værdi.
1> CREATE TABLE t (pk INTEGER PRIMARY KEY, v1 INTEGER, v2 INTEGER, v3 VARCHAR(50)) 2> GO 1> 2> INSERT INTO t VALUES(1, 11, 12, 'Bla bla') 3> GO (1 row affected) 1> INSERT INTO t VALUES(2, 11, 12, 'Der var engang') 2> GO (1 row affected) 1> INSERT INTO t VALUES(3, 21, 22, '...') 2> GO (1 row affected) 1> 2> SELECT * FROM t 3> GO pk v1 v2 v3 ----------- ----------- ----------- -------------------------------------------------- 1 11 12 Bla bla 2 11 12 Der var engang 3 21 22 ...
(3 rows affected) 1> 2> SELECT v1,v2,MAX(pk) maxpk FROM t GROUP BY v1,v2 3> GO v1 v2 maxpk ----------- ----------- ----------- 11 12 2 21 22 3
(2 rows affected) 1> 2> SELECT pk FROM t WHERE pk NOT IN (SELECT maxpk FROM (SELECT v1,v2,MAX(pk) max pk FROM t GROUP BY v1,v2) tagg) 3> GO pk ----------- 1
(1 row affected) 1> 2> DELETE FROM t WHERE pk NOT IN (SELECT maxpk FROM (SELECT v1,v2,MAX(pk) maxpk FROM t GROUP BY v1,v2) tagg) 3> GO (1 row affected) 1> 2> SELECT * FROM t 3> GO pk v1 v2 v3 ----------- ----------- ----------- -------------------------------------------------- 2 11 12 Der var engang 3 21 22 ...
Tja joe_dalton, det ser i hvert fald ud til at dit problem bliver løst.
arne_v's løsning er den rigtige hvis du har brug for at denne oprydning skal køre regelmæssigt. Det ville jo nok være nummer et hvis du i din programmering kunne sørge for at dubletterne ikke opstår igen.
Min løsning er "quick and dirty", og derfor let at forstå og hurtig at kode, men den er kun tænkt som en "engangs" ting.
Hvis din id, vi kalder den pk som arne gør, er identity, så kan du lave det sådan (tabellen hedder t og kolonnerne v1, v2 og v3):
--------------------
DECLARE @MaxPk int
SELECT MaxPk = Max(pk) FROM t
INSERT INTO t (v1, v2, v3) SELECT DISTINCT v1, v2, v3 FROM t
Ikke fordi det gør så meget, men du bad om en løsning, og du fik to. Hvorfor er det så at ingen af dem belønnes med point?
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.