2010-12-30 16 views
5

Ho una tabella che contiene dati sfortunatamente cattivi e sto cercando di filtrarne alcuni. Sono sicuro che la combonazione di LName, FName è unica in quanto il set di dati è abbastanza piccolo da essere verificato.SQL Rimuovi le righe quasi duplicate

LName, FName, Email 
----- ----- ----- 
Smith Bob [email protected] 
Smith Bob NULL 
Doe Jane NULL 
White Don [email protected] 

Mi piacerebbe avere i risultati della query riportare il record "duplicato" che non dispone di una e-mail NULL, ma ancora riportare un NULL e-mail quando non c'è un duplicato.

E.g.

Smith Bob [email protected] 
Doe Jane NULL 
White Don [email protected] 

Penso che la soluzione è simile a Sql, remove duplicate rows by value, ma io non capisco se i requisiti del richiedente sono uguale al mio.

Qualche suggerimento?

Grazie

+0

Grazie per le soluzioni di Cybernate e Michael Goldshteyn. Andato con FooLman b/c è stata la prima soluzione a fare il lavoro. Interessante vedere i diversi metodi per la risoluzione. – jimueller

risposta

7

Scende le righe nulle se sono presenti valori non nulle.

SELECT lname 
     , fname 
     , MIN(email) 
FROM YourTable 
GROUP BY 
     lname 
     , fname 

script di test

DECLARE @Test TABLE (
    LName VARCHAR(32) 
    , FName VARCHAR(32) 
    , Email VARCHAR(32) 
) 

INSERT INTO @Test 
    SELECT 'Smith', 'Bob', '[email protected]' 
    UNION ALL SELECT 'Smith', 'Bob', 'NULL' 
    UNION ALL SELECT 'Doe', 'Jane', 'NULL' 
    UNION ALL SELECT 'White', 'Don', '[email protected]' 

SELECT lname 
     , fname 
     , MIN(Email)   
FROM @Test 
GROUP BY 
     lname 
     , fname 
+1

+1 Questa è di gran lunga la * soluzione più semplice * che fa ciò che viene richiesto. La comunità sembra soffrire di sovrastenenza . –

+0

@Lieven - Non funzionerà comunque! Dove c'è una logica per mantenere le righe nulle se non ci sono quelle non nulle? –

+0

@Martin, la query produce l'output richiesto da op per gli input dati non lo ha (o ho ripreso a funzionare di nuovo)? –

3

Ecco una relativamente semplice query che utilizza SQL standard e lo fa proprio questo:

SELECT * FROM Person P 
WHERE Email IS NOT NULL OR -- Take all people with non-null e-mails 
     Email IS NULL AND -- and all people with null e-mails, as long as 
     NOT EXISTS   -- there is no duplicate record of the same person 
      (SELECT *  -- with a non-null e-mail 
      FROM Person P2 
      WHERE P2.LName=P.LName AND P2.FName=P.FName AND P2.Email IS NOT NULL) 
+0

Stai dicendo che 'row_number' non è SQL standard? –

+0

Non sto insinuando nulla: sto solo offrendo una soluzione semplice che utilizza nient'altro che una query SQL standard che coinvolge una sotto-selezione. Ma, se vuoi la risposta alla tua domanda relativa a ROW_NUMBER, no non è SQL standard e nemmeno PARTITION BY. –

+0

ANSI SQL 1999 [secondo qui] (http://ss64.com/ora/syntax-analytic.html) Non che SQL standard sia stato mai specificato dall'OP in ogni caso. –

7

È possibile utilizzare ROW_NUMBER) la funzione (analitica:

SELECT * 
    FROM (
       SELECT a.*, ROW_NUMBER() OVER(PARTITION BY LName, FName ORDER BY Email DESC) rnk 
        FROM <YOUR_TABLE> a 
       ) a 
WHERE RNK = 1 
+0

+1 Questo sarà probabilmente più efficiente di un self join. Questa tecnica può essere utilizzata per cancellare così come per la mia risposta. –

1

Poiché esistono già molte soluzioni SQL già pubblicate, è possibile creare una correzione dati per rimuovere i dati non validi, quindi aggiungere i vincoli necessari per impedire l'inserimento di dati non validi. I cattivi dati in un database sono un effetto collaterale di una progettazione scadente.

+0

Sono d'accordo e capisco, ma non posso farci molto in ambito IT aziendale. È la realtà dei dati con cui devo lavorare. – jimueller

+0

@ jrm82, è ancora più importante sistemare queste cose nelle applicazioni Enterprise! Solo perché è apin non significa che non dovresti farlo. Ciò non causerà mai la fine dei problemi se non si risolve. – HLGEM

+0

HLGEM - Io non "possiedo" i dati e non ho la capacità di lavorare su quello che voglio. – jimueller

Problemi correlati