Quiz SQL

Mi sono trovato a dover ripulire dei dati duplicati all’interno di una tabella, un problema che sembra abbastanza semplice ma che all’inizio mi ha creato qualche perplessità.

Alla fine la soluzione era molto più semplice di quanto pensassi, ho quindi pensato di proporre questo quiz per confrontare la mia soluzione con quelle proposte da chi vorrà cimentarsi per verificare se esistono soluzioni migliori e più performanti.

 

Ecco le specifiche del quiz:

 

User

Id

Int

pk

Cod

Char(16)

 

 

Bisogna eliminare tutte le duplicazioni sul campo Cod in modo tale che possa essere creato un indice univoco su quel campo.

Non bisogna utilizzare Stored Procedure ma va fatto tutto con un’unica istruzione SQL.

Il database su cui deve girare è SQL Server.

 

Buon lavoro a tutti quelli di buona volontà.

 

Technorati Tags:

posted @ giovedì 1 settembre 2005 13:25

Print

Comments on this entry:

# re: Quiz SQL

Left by Marco De Sanctis at 01/09/2005 13:47
Gravatar
Io ho pensato a questa:

delete from test
where id not in (
select min(id)
from test
group by cod
having count(cod) > 1)
and cod in
(select distinct cod
from test
group by cod
having count(cod) > 1)

# re: Quiz SQL

Left by Daniele Proietti at 01/09/2005 18:39
Gravatar
Nonostante ci siano stati numerosi accessi a questo post, è pervenuta solo una soluzione. Probabilmente i visitatori sono stati scoraggiati dal fatto che Marco ha proposto una soluzione corretta dopo appena 22 minuti dalla pubblicazione (complimenti Marco).
La soluzione che avevo adottato io era leggermente diversa:
delete from dbo.[user] where exists (
select user02.cod from dbo.[user] as user02
where user02.cod = [user].cod
group by user02.cod having count(*) > 1 ) and
[user].id > (select min(user01.id) from dbo.[user] as user01 where user01.cod = [user].cod)

Siccome la tabella contiene un elevato numero di righe ho effettuato una serie di analisi per verificare quale fosse la soluzione migliore in termini di prestazioni.
Il risultato è stato interessante visto che, nonostante il piano di esecuzione delle due query sia molto diverso, i risultati in termini di performance sono assolutamente identici; probabilmente non è possibile ottimizzare più di così.

Se qualcuno avesse altre soluzioni da proporre sarò comunque lieto di verificarne le prestazioni.

# re: Quiz SQL

Left by Marco De Sanctis at 01/09/2005 20:41
Gravatar
eheheh! Grazie dei complimenti!! :)

# re: Quiz SQL

Left by Paolo Gregorio at 03/09/2005 13:42
Gravatar
Mi rendo conto adesso che è molto più leggibile scambiando i nomi Test e TestDup:

DELETE TestDup
FROM
Test TestDup
INNER JOIN Test
ON
TestDup.Cod = Test.Cod
AND TestDup.Id > Test.Id

# re: Quiz SQL

Left by Daniele Proietti at 05/09/2005 12:09
Gravatar
Ho analizzato con interesse anche la soluzione proposta da Paolo e debbo dire che è risultata la migliore delle tre in termini di performance.
Il piano di esecuzione è ovviamente molto diverso, perché anche l'approccio è diverso, ed il risultato in termini di performance è risultato leggermente migliore rispetto agli altri due; da una prima analisi penso dipenda dal fatto che questo piano di esecuzione preveda un utilizzo della CPU notevolmente più basso rispetto ai precedenti.

Complimenti quindi anche a Paolo che, anche se arrivato in ritardo ha proposto la soluzione più performante.
Ovviamente se qualcun altro vuole cimentarsi sono sempre pronto a fare le verifiche del caso

# re: Quiz SQL

Left by vietanh at 12/01/2006 11:15
Gravatar
fghg
Comments have been closed on this topic.
«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011