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

发布于 2024-08-18 21:18:56 字数 537 浏览 4 评论 0原文

我正在编写一个报告存储过程。我想要获取未确认和未开票的采购订单的数量,并能够(可选)筛选 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

I'm writing a reporting stored procedure. I want to get the number of non-Acknowledged and non-Invoiced Purchase Orders, with the ability to (optionally) filter on CustomerID.

What I have below works as expected, but I worry that a) it's slow and b) there's duplication in the CustomerID portion of the WHERE clause.

How would you write this stored proc, 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小梨窩很甜 2024-08-25 21:18:56

像这样的事情:

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) 

Something like this:

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) 
故笙诉离歌 2024-08-25 21:18:56

我不确定 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

I'm not sure 100% what you are after, but you could simplify the customer part as follows: (untested from [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
我不在是我 2024-08-25 21:18:56

您不能使用:

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

You can't use:

  • COUNT because it will count all rows (1 or 0 is not null so it counts them)
  • COUNT DISTINCT will give 2 (only values 1 and 0)

If you remove the status checks it will run faster of course if you can deal with zeros.

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文