1

我在寫報告存儲過程。我想獲得未確認和非開票採購訂單的數量,並可以(可選)在CustomerID上過濾。報告存儲過程 - 如何避免重複?

我在下面的工作如預期,但我擔心,a)它很慢,b)WHERE條款的CustomerID部分有重複。

你會如何編寫這個存儲過程,堆棧溢出?

SELECT 
    (SELECT COUNT(*) 
    FROM PurchaseOrder 
    WHERE AcknowledgmentStatus <> 'Complete' 
    AND (@CustID = 0 OR CustomerID = @CustID) 
) AS NonAckd, 
    (SELECT COUNT(*) 
    FROM PurchaseOrder 
    WHERE InvoiceStatus <> 'Complete' 
    AND (@CustID = 0 OR CustomerID = @CustID) 
) AS NonInvoiced 

回答

2

像這樣的東西(從[累]內存未經):

SELECT Sum(Case When AcknowledgmentStatus <> 'Complete' Then 1 ELSE 0 END) as NonAckd 
     ,Sum(Case When InvoiceStatus <> 'Complete'  Then 1 ELSE 0 END) as NonInvoiced 
    FROM PurchaseOrder 
WHERE CustomerID = IsNull(NullIf(@CustID, 0), CustomerID) 
+0

這就是我一直在尋找的東西!我不敢相信我從未見過'CASE WHEN'結構。 – 2010-01-26 18:45:22

2

我不是100%肯定你是什麼後,但你可以如下簡化客戶的部分:

set @custID = nullif(@custID,0) 

SELECT 
    (SELECT COUNT(*) 
    FROM PurchaseOrder 
    WHERE AcknowledgmentStatus <> 'Complete' 
    AND (CustomerID = isnull(@CustID,CustomerID)) 
) AS NonAckd, 
    (SELECT COUNT(*) 
    FROM PurchaseOrder 
    WHERE InvoiceStatus <> 'Complete' 
    AND (CustomerID = isnull(@CustID,CustomerID)) 
) AS NonInvoiced 
+0

我認爲他想擺脫重複代碼的太... – 2010-01-26 18:38:57

+0

用好NULLIF的,謝謝。我會將其添加到我的最終處理程序中。 – 2010-01-26 18:46:05

1

不能使用:

  • COUNT,因爲它會湊NT所有行(1或0不是空,因此它計數它們)
  • COUNT DISTINCT會給2(只值1和0)

如果刪除狀態檢查它將運行,如果你當然更快可以處理零。

SELECT 
    CASE WHEN AcknowledgmentStatus <> 'Complete' THEN 1 ELSE 0 END AS NonAckd, 
    CASE WHEN InvoiceStatus <> 'Complete' THEN 1 ELSE 0 END AS NonInvoiced, 
FROM 
    PurchaseOrder 
WHERE 
    (AcknowledgmentStatus <> 'Complete' OR InvoiceStatus <> 'Complete') --optional 
    AND 
    (@CustID = 0 OR CustomerID = @CustID)