2013-07-09 22 views
7

Prima che qualcuno faccia un rant che questa tabella debba essere normalizzata, best practice, ecc. Ammetto che si tratta di una vecchia tabella che abbiamo in SQL Server 2008 R2 e Non posso fare nulla per cambiarlo. Detto questo, questa tabella ha le seguenti colonne:Ricerca di valori duplicati in colonne diverse nella stessa riga

"PreparedBy", "PrelimApprovalBy", "Approval1Signer", "Approval2Signer" 

Tutti questi campi hanno nomi utente o NULL o "". Voglio ottenere tutte le righe in cui lo stesso nome utente appare in 2 o più dei campi sopra menzionati. Se 2 campi sono NULL sono NON una corrispondenza e sono NON una corrispondenza se sono entrambi ''. Quindi sia NULL che '' devono essere esclusi in quanto non significano nulla.


Ecco quello che ho pensato di finora, ma non sono gradire:
Sto pensando di controllare tutte le permutazioni nella clausola WHERE (controllando per NULL e '') facendo qualcosa lungo le linee di

WHERE PreparedBy = PrelimApprovalBy OR PreparedBy = Approval1Signer OR ... 

Ci deve essere un modo migliore per farlo.

risposta

7

Eccone uno:

SELECT * FROM T 
WHERE EXISTS 
    (SELECT 1 
     FROM (VALUES 
        (PreparedBy) 
        ,(PrelimApprovalBy) 
        ,(Approval1Signer) 
        ,(Approval2Signer)) AS X (n) 
     WHERE NULLIF(n, '') IS NOT NULL 
     GROUP BY n 
     HAVING COUNT(*)>1 
    ) 

In sostanza, per ogni riga, stiamo costruendo un mini-tabella con i valori delle colonne in righe diverse, e facendo un GROUP BY e di dover verificare la presenza di gruppi di valori corrispondenti . NULLIF ci sta aiutando a ignorare i valori "" (rendendoli NULL e quindi escludendo tutti i NULL).

+0

È fantastico! Funziona! Mai visto questa sintassi prima ... FROM (VALUES ... AS X (n)). Ho imparato qualcosa di nuovo oggi! – Denis

+0

Felice di aiutare e di presentare una nuova sintassi. Più strumenti nella cintura degli attrezzi non possono ferire. Inoltre, questa soluzione può facilmente gestire più colonne, mentre l'altro metodo esploderà in dimensioni e complessità molto presto. – GilM

+0

+1 sembra pulito. funziona su qualsiasi server sql? –

2

Prova questa ricerca:

SELECT PreparedBy, PrelimApprovalBy, Approval1Signer, Approval2Signer 
WHERE 
((PreparedBy = PrelimApprovalBy AND NULLIF(PreparedBy, '') IS NOT NULL) 
OR 
(PreparedBy = Approval1Signer AND NULLIF(PreparedBy, '') IS NOT NULL) 
OR 
(PreparedBy = Approval2Signer AND NULLIF(PreparedBy, '') IS NOT NULL) 
OR 
(PrelimApprovalBy = Approval1Signer AND NULLIF(PrelimApprovalBy, '') IS NOT NULL) 
OR 
(PrelimApprovalBy = Approval2Signer AND NULLIF(PrelimApprovalBy, '') IS NOT NULL) 
OR 
(Approval1Signer = Approval2Signer AND NULLIF(Approval1Signer, '') IS NOT NULL)) 

Non riesco a pensare a niente di più semplice per ottenere ciò che cercate per.

+0

questo non funzionerà! Cosa succede se PreparedBy IS NULL e Approval1Signer = Approval2Signer. Vorrei che quel record ma la tua query lo escludesse perché PreparedBy IS NULL. – Denis

+0

@Denis Ho appena cambiato di conseguenza. Dovrebbe funzionare ora. :) –

+0

@Denis Sembra abbastanza brutto - ma poi ancora: non riesco a pensare a niente di più facile che possa ottenere i risultati che stai cercando. –

Problemi correlati