【问题标题】:Running total of values from a table until it matches value from another table运行表中的值总计,直到它与另一个表中的值匹配
【发布时间】:2018-10-09 19:10:43
【问题描述】:

我有 2 张桌子。

表1是一个临时变量表​​:

declare @Temp as table ( proj_num varchar(10), sum_dom decimal(23,8))

我的临时表中包含项目编号列表和月末会计金额。
例如:

proj_num |  sum_dom
11522    |  2477.15
11524    | 26474.20
41865    |  9012.10

表 2 是一个项目事务表。 我们只关心以下列:

  • proj_num
  • amount
  • cost_code
  • tran_date

个人价值观会是这样的:

proj_num | cost_code | amount  | tran_date
11522    | LBR       |  112.10 | 10/1/2018
11522    | LBR       | 1765.90 | 10/2/2018
11522    | MAT       |  599.15 | 10/3/2018
11522    | FRT       |   57.50 | 10/4/2018

因此,对于这个项目,由于 2477.15 美元的总额在 10 月 3 日达到,示例输出将是:

proj_num | cost_code | amount 
11522    |  LBR      | 1878.00
11522    |  MAT      | 599.15

我想对项目事务表下的金额(按 cost_code 分组,并按 tran_date 排序)求和,直到该项目值的总和与 temp 表的 sum_dom 列中的值匹配,此时我将输出该数据。

你能帮我弄清楚如何编写查询来做到这一点吗? 我知道我应该避免使用游标,但到目前为止我的尝试并没有太多运气。我似乎无法让它保持运行总数。

【问题讨论】:

  • 如果没有匹配有可能吗?为什么它会像那个顺序一样排序?如果是从下往上显示呢?
  • @LONG 我不确定我是否理解你的问题。所有记录都将匹配。为简单起见,我只包括了几个顶级项目编号的示例。我需要事务表中的记录按 tran_date asc 排序。
  • 我在考虑如何避免在您获得正确金额之前计算 57.5 美元
  • 您似乎混淆了代码和数量。

标签: sql sql-server cumulative-sum database-cursor


【解决方案1】:

运行总和是使用SUM(...) OVER (ORDER BY ...) 完成的。你只需要告诉在哪里停止:

SELECT sq.*
FROM projects
INNER JOIN (
    SELECT
        proj_num,
        cost_code,
        amount,
        SUM(amount) OVER (PARTITION BY proj_num ORDER BY tran_date) AS running_sum
    FROM project_transactions
) AS sq ON projects.proj_num = sq.proj_num
WHERE running_sum <= projects.sum_dom

DB Fiddle

【讨论】:

  • 看起来它不适用于我的主数据库(SQL 服务器版本太旧?),但它确实适用于更新版本的链接服务器。现在我只需要弄清楚如何加快速度,因为它非常慢(平均 40 秒/项目编号)。所以我会调查一下。但是,这是一个可行的解决方案,非常感谢!
  • SUM() OVER 我相信需要 SQL 2008。您始终可以添加适当的WHERE 子句并创建索引以加快速度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多