2013-07-09 11 views
7

Zanim ktoś powie, że ta tabela powinna zostać znormalizowana, najlepsze praktyki itp. Przyznam, że jest to stara tabela, którą mamy w SQL Server 2008 R2 i Nie mogę nic zrobić, żeby to zmienić. Po tym, ta tabela ma następujące kolumny:Znajdowanie zduplikowanych wartości w różnych kolumnach w tym samym wierszu

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

Wszystkie te pola mają nazwy użytkownika lub NULL lub "". Chcę uzyskać wszystkie wiersze, w których ta sama nazwa użytkownika pojawia się w 2 LUB WIĘCEJ pól wymienionych powyżej. Jeśli 2 pola mają wartość NULL, są one zgodne z NOT i są zgodne z ustawą NOT, jeśli oba są "". Tak więc zarówno NULL, jak i "muszą być wykluczone, ponieważ nic nie znaczą.


oto co pomyślałem o tak daleko, ale nie jestem gustu IT:
myślę o sprawdzeniu wszystkich permutacji w klauzuli WHERE (sprawdzanie NULL i „”), robiąc coś wzdłuż linii z

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

Musi być lepszy sposób na zrobienie tego.

Odpowiedz

7

Oto jeden:

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 
    ) 

W zasadzie dla każdego wiersza, jesteśmy konstruowania mini-tabeli z wartościami kolumn w różnych wierszach, a robi GROUP BY i konieczności sprawdzenia grup odpowiadających wartości . NULLIF pomaga nam zignorować "wartości" (czyniąc je NULL, a następnie wykluczając wszystkie NULL).

+0

To jest niesamowite! To działa! Nigdy nie widziałem tej składni przed ... OD (WARTOŚCI ... AS X (n)). Nauczyłem się dzisiaj czegoś nowego! – Denis

+0

Cieszę się, że mogę pomóc i przedstawić nową składnię. Więcej narzędzi w pasku narzędzi nie zaszkodzi. Również to rozwiązanie może z łatwością obsłużyć więcej kolumn, podczas gdy druga metoda szybko eksploduje pod względem wielkości i złożoności. – GilM

+0

+1 wygląda schludnie. czy to działa dla dowolnego serwera sql? –

2

Spróbuj zapytanie:

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)) 

nie mogę myśleć o niczym prostsza do osiągnięcia, czego szukać.

+0

to nie zadziała! Co się stanie, jeśli PreparedBy JEST NULL i Approval1Signer = Approval2Signer. Chciałbym ten rekord, ale zapytanie go wyklucza, ponieważ PreparedBy IS NULL. – Denis

+0

@Denis Właśnie zmieniłem to odpowiednio. Powinien teraz działać. :) –

+0

@Denis Wygląda dość brzydko - ale z drugiej strony: nie mogę wymyślić nic łatwiejszego, co przyniosłoby oczekiwane rezultaty. –

Powiązane problemy