Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL中的同一查询中引用上一次计算的输出?_Sql_Sql Server_Recursion_Recursive Query - Fatal编程技术网

如何在SQL中的同一查询中引用上一次计算的输出?

如何在SQL中的同一查询中引用上一次计算的输出?,sql,sql-server,recursion,recursive-query,Sql,Sql Server,Recursion,Recursive Query,我对SQL还是相当陌生,我正在尝试执行一个计算,该计算引用了在前一行/时间段对同一个表执行的计算的输出 [表格样本] | Full Part | Quarter Yr | Name | Value | |-----------|------------|---------------|-----------| | 470205-17 | 42019 | Q1 FY 20 CCBP | 12524 | | 470205-17 | 42019

我对SQL还是相当陌生,我正在尝试执行一个计算,该计算引用了在前一行/时间段对同一个表执行的计算的输出

[表格样本]

| Full Part | Quarter Yr | Name | Value | |-----------|------------|---------------|-----------| | 470205-17 | 42019 | Q1 FY 20 CCBP | 12524 | | 470205-17 | 42019 | Q1 FY 20 SP | 579.0005 | | 470205-17 | 42019 | Q1 FY 21 CCBP | 17436 | | 470205-17 | 42019 | Q1 FY 21 SP | 885.9997 | | 470205-17 | 42019 | Q2 FY 20 CCBP | 14807 | | 470205-17 | 42019 | Q2 FY 20 SP | 764.9999 | | 470205-17 | 42019 | Q2 FY 21 CCBP | 15220 | | 470205-17 | 42019 | Q2 FY 21 SP | 851.9996 | | 470205-17 | 42019 | Q3 FY 20 CCBP | 16196 | | 470205-17 | 42019 | Q3 FY 20 SP | 1066.9998 | | 470205-17 | 42019 | Q4 FY 19 CCBP | 4841 | | 470205-17 | 42019 | Q4 FY 19 SP | 730.0005 | | 470205-17 | 42019 | Q4 FY 20 CCBP | 17100 | | 470205-17 | 42019 | Q4 FY 20 SP | 1115.9995 | | 470205-17 | 42019 | Total QOH | 2181 | SP是预测,QOH是当前库存,CCBP是供应

我需要的是第四季度YR=42019的产出(总QOH+19财年第四季度CCBP)-19财年第四季度SP

然后,对于季度Yr=12020,我需要期末存货(上一次计算的输出)+(第1季度20财年CCBP)-第1季度20财年SP

依此类推,直到QuarterYr=22021

输出需要采用相同的格式,即完整部分、四分之一、名称=‘期末存货’、值

| Full Part | Quarter Yr | Name | Value | |-----------|------------|------------------|-------| | 470205-17 | 42019 | Ending Inventory | 6292 | | 470205-17 | 12020 | Ending Inventory | 18237 | | 470205-17 | 22020 | Ending Inventory | 32280 | | 470205-17 | 32020 | Ending Inventory | 47409 | | 470205-17 | 42020 | Ending Inventory | 63393 | | 470205-17 | 12021 | Ending Inventory | 79944 | | 470205-17 | 22021 | Ending Inventory | 94313 | |完整部分|季度年|名称|价值| |-----------|------------|------------------|-------| |470205-17 | 42019 |期末存货| 6292 | |470205-17 | 12020 |期末存货| 18237 | |470205-17 | 22020 |期末存货| 32280 | |470205-17 | 32020 |期末存货| 47409 | |470205-17 | 42020 |期末存货| 63393 | |470205-17 | 12021 |期末存货| 79944 | |470205-17 | 22021 |期末存货| 94313 | 我假设这需要递归/for循环来实现所需的输出。
非常感谢您在这方面提供的任何帮助。

在SQL Server 2017上测试:

下面是生成所需结果的示例查询:

declare @mytable table(
   Full_Part  VARCHAR(9) NOT NULL
  ,Quarter_Yr INTEGER  NOT NULL
  ,Name       VARCHAR(13) NOT NULL
  ,Value      NUMERIC(9,4) NOT NULL
);

INSERT INTO @mytable(Full_Part,Quarter_Yr,Name,Value) VALUES
 ('470205-17',42019,'Q1 FY 20 CCBP',12524)
,('470205-17',42019,'Q1 FY 20 SP',579.0005)
,('470205-17',42019,'Q1 FY 21 CCBP',17436)
,('470205-17',42019,'Q1 FY 21 SP',885.9997)
,('470205-17',42019,'Q2 FY 20 CCBP',14807)
,('470205-17',42019,'Q2 FY 20 SP',764.9999)
,('470205-17',42019,'Q2 FY 21 CCBP',15220)
,('470205-17',42019,'Q2 FY 21 SP',851.9996)
,('470205-17',42019,'Q3 FY 20 CCBP',16196)
,('470205-17',42019,'Q3 FY 20 SP',1066.9998)
,('470205-17',42019,'Q4 FY 19 CCBP',4841)
,('470205-17',42019,'Q4 FY 19 SP',730.0005)
,('470205-17',42019,'Q4 FY 20 CCBP',17100)
,('470205-17',42019,'Q4 FY 20 SP',1115.9995)
,('470205-17',42019,'Total QOH',2181);

WITH PARSE1 AS (
    SELECT 
        CASE WHEN Name LIKE 'Q_ FY%' THEN SUBSTRING(Name,2,1)  ELSE NULL END AS N1,
        CASE WHEN Name LIKE 'Q_ FY%' THEN SUBSTRING(Name,7,2)  ELSE NULL END AS N2,
        CASE WHEN Name LIKE 'Q_ FY%' THEN SUBSTRING(Name,10,4) 
             WHEN NAME = 'Total QOH' THEN 'QOH' ELSE NULL END AS N3,
        Full_Part, Quarter_Yr, Value
    FROM @mytable
), PARSE2 AS (
    SELECT Full_Part, Quarter_Yr, Value, N3, CASE WHEN N3 = 'SP' THEN -1 ELSE 1 END AS mValue, CAST(N1 AS INT) AS Q, 2000 + CAST(N2 AS INT) AS YR
    FROM PARSE1
), PIVOT1 AS (
    SELECT Q, YR, Full_Part, Quarter_Yr, SUM(Value * mValue) AS Qtr_Value 
    FROM PARSE2
    GROUP BY Q, YR, Full_Part, Quarter_Yr
), ANALYTIC1 AS (
    SELECT Q, YR, Full_Part, Quarter_Yr, Qtr_Value,
        SUM(Qtr_Value) OVER (PARTITION BY [Full_Part] ORDER BY YR, Q) AS Run_Value
    FROM PIVOT1
) 
SELECT Full_Part AS [Full Part], CONCAT(Q,YR) AS [Quarter Yr], 'Ending Inventory' AS Name, CAST(ROUND(Run_Value,1) AS INT) AS Value
FROM ANALYTIC1 
WHERE Q IS NOT NULL

输出:

Full Part   Quarter Yr  Name                Value
470205-17   42019       Ending Inventory    6292
470205-17   12020       Ending Inventory    18237
470205-17   22020       Ending Inventory    32279
470205-17   32020       Ending Inventory    47408
470205-17   42020       Ending Inventory    63392
470205-17   12021       Ending Inventory    79942
470205-17   22021       Ending Inventory    94310
关于不同的通用表表达式-CTE(s)

PARSE1/PARSE2:

  • 一些关键数据隐藏在字符串“Name”中
  • 我们需要提取数据类型、季度和年度信息(假设2000+两位数可用)
  • 我们还将计划通过将该值乘以负1来减去SP
数据透视1:

  • 现在我们可以应用我们的分组功能来总结季度部分
分析1:

  • 使用一个特殊的求和分析函数,我们可以在按季度/年订购时创建一个运行计数
  • 包含一个partition by子句,用于在每个逻辑数据集中创建一个运行计数
最终选择:

  • 提供最终的清理查询,以根据需要显示数据
可以使用天花板()或地板()替换圆形()以微调结果

要检查每个单独的CTE,您可以将最终选择替换为:

  • 从PARSE1中选择*
  • 从PARSE2中选择*
  • 从数据透视1中选择*
  • 从分析1中选择*

请不要发布截图。请发布文本,以便我们可以根据测试需要剪切/粘贴。我们不会逐一键入样本数据。如果您希望任何人帮助您,请为这些数据提供CREATETABLE和insert语句。对此表示抱歉。这是我第一次来这里。现在添加了表。在第一行输出中,如何获得值6292?从您的公式2181+17100-1115.9995=18165.0005您看到的是20财年第4季度,而不是19财年第4季度2181+4841-730=6292谢谢,解决方案比我预期的简单得多。乘以-1并执行运行计算是一个好主意。顺便说一句,我建议对正在运行的calc查询进行编辑以使用分区依据,因为表中有多个部分。我很高兴听到示例引导您找到所需的解决方案。您是正确的,如果在较大的数据集中有部分或逻辑组,您希望在该集合的id上有分区by,以便在每个分区中有一个单独的运行计数。
Full Part   Quarter Yr  Name                Value
470205-17   42019       Ending Inventory    6292
470205-17   12020       Ending Inventory    18237
470205-17   22020       Ending Inventory    32279
470205-17   32020       Ending Inventory    47408
470205-17   42020       Ending Inventory    63392
470205-17   12021       Ending Inventory    79942
470205-17   22021       Ending Inventory    94310