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

Posted

技术标签:

【中文标题】报告存储过程 - 如何避免重复?【英文标题】:Reporting Stored Procedure - How to avoid duplication? 【发布时间】:2010-01-26 18:29:28 【问题描述】:

我正在编写一个报告存储过程。我想获取未确认和未开票的采购订单的数量,并能够(可选)过滤CustomerID

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

你会如何编写这个存储过程,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

【问题讨论】:

【参考方案1】:

类似这样的:

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) 

【讨论】:

这正是我一直在寻找的东西!我不敢相信我从未见过CASE WHEN 结构。【参考方案2】:

我不确定 100% 你在追求什么,但你可以将客户部分简化如下:(未经 [tired] memory 测试)

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

【讨论】:

【参考方案3】:

你不能使用:

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)

【讨论】:

以上是关于报告存储过程 - 如何避免重复?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何避免并行执行存储过程?

SQL执行插入时,遇到重复键值时,如何设置才能让新插入的数据覆盖原有旧数据;要用存储过程么?

如何避免存储过程中不必要的重新编译?

在 Java 中调用 Oracle 存储过程时如何避免核心转储

存储过程和函数

s-s-rS 报告未从存储过程中提取数据