【问题标题】:TSQL Help Without Cursor没有光标的 TSQL 帮助
【发布时间】:2021-11-07 23:31:38
【问题描述】:

我有以下数据,我需要的输出在列中:新库存。目前使用 Cursor 导出值,但随着源表中记录数的增加存在性能问题。

ID Item Inventory Projected Shipment Receipt LinkDate NewInventory
1 Item1 '10' '2' '5' '01-Sep-2021' '13'
1 Item2 '20' '3' '8' '02-Sep-2021' '18'
1 Item3 '30' '8' '15' '03-Sep-2021' '25'
2 Item4 '40' '10' '20' '01-Sep-2021' '50'
2 Item5 '50' '25' '20' '02-Sep-2021' '45'
2 Item6 '60' '10' '20' '03-Sep-2021' '55'

这是计算值的方式:对于基于 ID Order by LinkDate 的每个分区,第一行将基于以下公式:

NewInventory = Inventory+Receipt-ProjectedShipment

所以第一条记录变成:10+5-3 =13。该值将成为基础库存,并将在后续行中用于计算同一分区中的新库存。

对于 ID=1 的实例 'Item2'

New Inventory = Previous calculated NewInventory + Current Row Receipt- Current Row Projected Shipment

变成这样

新库存 = 13 + 8- 3-- 这变成 18

目前所有这些逻辑都是在 Cursor 的帮助下实现的。请让我知道是否有仅使用 tsql 的直接方法以解决当前的性能问题。

请帮忙。

提前致谢

【问题讨论】:

  • 您是按ID 还是Item 分区? Item 究竟代表什么?
  • First record becomes : 10+5-3 =13 你第一行的“3”是从哪里来的? your 版本的结果是 12,而不是 13。

标签: sql sql-server tsql window-functions


【解决方案1】:

您可以使用FIRST_VALUE()SUM() 窗口函数来做到这一点:

SELECT *, 
       FIRST_VALUE(Inventory) OVER (PARTITION BY ID ORDER BY LinkDate) +
       SUM(Receipt - ProjectedShipment) OVER (PARTITION BY ID ORDER BY LinkDate) NewInventory
FROM tablename;

请参阅demo

【讨论】:

  • 哦,用完全相同的代码打败我。虽然我会在两个OVERs 中添加ROWS UNBOUNDED PRECEDING,以防日期重复,但它的性能也更高
  • 谢谢!为了您的帮助,您的逻辑确实对我有用。
【解决方案2】:

它只适用于 SUM() OVER

SELECT *, 
       SUM(Inventory + Receipt - ProjectedShipment) OVER (PARTITION BY ID ORDER BY LinkDate) NewInventory
FROM tablename;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    相关资源
    最近更新 更多