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)