【问题标题】:How to Reference Calculated Value from previous line to find next calculated value如何从上一行引用计算值以查找下一个计算值
【发布时间】:2019-10-03 18:00:14
【问题描述】:

尝试根据表中的值计算新字段。计算出第一个字段后,需要在后面的行引用前一个值才能开始下一个计算。

已尝试使用滞后/领先功能,因为我需要进行分区。

declare @test as table (
[Worked Hours] decimal(2,0),
[Sold Hours] decimal(3,0),
[Current Backlog] decimal(3,0),
[Product] nvarchar(10),
[Revenue Type] nvarchar(3),
[Month] date
)

INSERT INTO @TEST 
([Worked Hours], [Sold Hours], [Current Backlog], [Product], [Revenue Type], [Month])

VALUES
('10','150','50', 'Product', 'Revenue', '01-01-2019'),
('25','200','50', 'Product', 'Revenue', '02-01-2019'),
('15','175','50', 'Product', 'Revenue', '03-01-2019'),
('40','250','50', 'Product', 'Revenue', '04-01-2019')


select 

t.[Product],
t.[Revenue Type],
t.[Month],
t.[Worked Hours],
t.[Sold Hours],
t.[Current Backlog]

from @test as T

我的预期结果将是一个使用此数学的新列。

T.[Current Backlog] - T.[Worked Hours] + T.[Sold Hours] = 'New Backlog'(对于第一行,这将是 190)。

随后的行将使用“新积压值”(190) 代替上一个等式中的 T.[Current Backlog]。

Overall Expected Results

Product Revenue 2019-01-01  10  150 50    190
Product Revenue 2019-02-01  25  200 50    365
Product Revenue 2019-03-01  15  175 50    525
Product Revenue 2019-04-01  40  250 50    735

【问题讨论】:

    标签: sql tsql


    【解决方案1】:

    我想你想要一个累积的总和:

    select t.*,
           [Current Backlog] + sum([Sold Hours] - [Worked Hours]) over (order by [Month])
    from @test t;
    

    Here 是一个 dbfiddle。

    【讨论】:

    • 运行总计正在工作,但是它包括第一行的原始 [Current Backlog]。在第一行之后,我需要忽略 [Current Backlog] 并将其替换为正在创建的 [New Backlog]。
    • @mz1815 。 . .您不希望积压,只是其他两个字段的差异。这仍然是一个简单的累积和。
    【解决方案2】:

    我会使用递归 CTE 来解决这个问题。您需要对记录进行排名和计数,然后递归处理每条记录,同时分配新的积压值。

    考虑:

    WITH 
    tab AS (
        SELECT
            t.*,
            ROW_NUMBER() OVER(ORDER BY [Month]) rn,
            COUNT(*) OVER() cnt
        FROM @test t
    ),
    cte AS (
        SELECT 
            [Product], 
            [Revenue Type],
            [Month],
            [Worked Hours],
            [Sold Hours],
            CAST([Current Backlog] as integer) 
                - CAST([Worked Hours] as integer) 
                + CAST([Sold Hours] as integer) [New Backlog],
            cnt,
            1 n
        FROM tab t
        WHERE t.rn = 1
        UNION ALL
        SELECT 
            t.[Product],
            t.[Revenue Type],
            t.[Month],
            t.[Worked Hours],
            t.[Sold Hours],
            c.[New Backlog] 
                - CAST(t.[Worked Hours] AS integer) 
                + CAST(t.[Sold Hours] AS integer) [New Backlog],
                t.cnt,
                c.n + 1
        FROM tab t
        INNER JOIN cte c ON t.rn = c.n + 1
        WHERE c.n <= t.cnt
    )
    SELECT 
        [Product],
        [Revenue Type],
        [Month],
        [Worked Hours],
        [Sold Hours],
        [New Backlog]
    FROM cte;
    

    Demo on DB Fiddle

    产品 |收入类型 |月 |工作时间 |销售时间 |新积压 :-------- | :----------- | :----------------- | :----------- | :--------- | ----------: BBCRM |测试与测量 | 01/01/2019 00:00:00 | 10 | 150 | 190 BBCRM |测试与测量 | 01/02/2019 00:00:00 | 25 | 200 | 365 BBCRM |测试与测量 | 01/03/2019 00:00:00 | 15 | 175 | 525 BBCRM |测试与测量 | 01/04/2019 00:00:00 | 40 | 250 | 735

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多