2013-07-09 149 views
7

在有人進行咆哮之前,應該對該表進行規範化,最佳實踐等。我將承認這是我們在SQL Server 2008 R2中的舊錶,並且我無法改變它。話雖如此,此表格有以下列:在同一行的不同列中查找重複值

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

所有這些字段都有用戶名或NULL或''。我想要獲取所有在上面提到的字段中出現的相同用戶名的行。如果2個字段爲空,他們是不是一場比賽,他們是不是匹配,如果他們都是''。所以NULL和''都需要排除,因爲它們不表示任何東西。


這是我至今認爲,但是我不喜歡它:由沿線做一些
我想檢查WHERE子句中的所有排列的(檢查NULL和「」)的

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

有一個更好的方法來做到這一點。

回答

7

這裏有一個:

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 
    ) 

基本上,對於每一行,我們正在構建一個小型表中不同行的列值,並做了GROUP BY和HAVING檢查匹配值的組。 NULLIF幫助我們忽略''值(使它們爲NULL,然後排除所有NULL)。

+0

這太棒了!有用!從...(VALUES ... AS X(n))之前從未看到過此語法。我今天學了些新東西! – Denis

+0

很高興提供幫助,並提出新的語法。工具帶中的更多工具不會受到傷害。此外,該解決方案可以輕鬆處理更多列,而另一種方法很快就會在大小和複雜度上爆炸。 – GilM

+0

+1看起來很整齊。這是否適用於任何SQL Server? –

2

嘗試此查詢:

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

我想不出什麼simplier達到你尋求的東西。

+0

這不行!如果PreparedBy IS NULL和Approval1Signer = Approval2Signer。我想要那個記錄,但是你查詢會排除它,因爲PreparedBy IS NULL。 – Denis

+0

@Denis我只是相應地改變了它。現在應該工作。 :) –

+0

@Denis它看起來相當醜陋 - 但後來:我想不出任何更容易得到你要找的結果的東西。 –

相關問題