报告存储过程 - 如何避免重复?

时间:2010-01-26 18:29:29

标签: sql sql-server stored-procedures refactoring query-optimization

我正在撰写报告存储过程。我想获得非确认和非开票的采购订单的数量,能够(可选)过滤CustomerID

我下面的内容按预期工作,但我担心a)它很慢而且b)CustomerID子句的WHERE部分有重复。

你会如何编写这个存储过程,Stack Overflow?

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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) 

答案 2 :(得分:1)

你不能使用:

  • COUNT因为它会计算所有行(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)