如何在 SQL 中的同一查询中引用先前计算的输出?
How to reference the output of a previous calculation within the same query in SQL?
我对 SQL 还是很陌生,我正在尝试执行一个计算,该计算引用了在之前 [=31] 中对相同 table 执行的计算的输出=]期间。
[table]
样本
| 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 |
CREATE TABLE mytable(
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);
SP 是预测,QOH 是当前库存,CCBP 是供应
我需要的 YR=42019 季度输出是(总 QOH+Q4 FY 19 CCBP)-Q4 FY 19 SP
然后对于 Yr=12020 季度,我需要期末库存(先前计算的输出)+(Q1 FY 20 CCBP)-Q1 FY 20 SP
以此类推,直到 QuarterYr=22021
输出需要采用相同的格式,即 Full Part、QuartrYr、Name='Ending Inventory'、Value
| 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 |
我假设这需要 recursion/for 循环才能获得所需的输出。
将不胜感激对完成这项工作的任何帮助。
在 SQL 服务器 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
关于不同的通用 Table 表达式 - CTE
PARSE1/PARSE2:
- 字符串中隐藏了一些关键数据"Name"。
- 我们需要提取数据类型、季度和年份信息(假设 2000 + 两位可用)。
- 我们还计划通过将值乘以负 1 来减去 SP。
枢轴 1:
- 现在我们可以应用我们的分组功能来总结季度部分。
分析 1:
- 使用特殊的总和分析函数,我们可以在按 Quarter_Yr 排序时创建一个 运行 计数。
- 包含一个分区子句以在每个逻辑数据集中创建一个 运行 计数。
决赛 SELECT:
- 提供最终清理查询以根据需要显示数据。
您可以将 ROUND() 替换为 CEILING() 或 FLOOR() 以微调结果。
要检查每个单独的 CTE,您可以将最终的 select 替换为:
- SELECT * 来自 PARSE1
- SELECT * 来自 PARSE2
- SELECT * 来自 PIVOT1
- SELECT * 来自分析 1
我对 SQL 还是很陌生,我正在尝试执行一个计算,该计算引用了在之前 [=31] 中对相同 table 执行的计算的输出=]期间。
[table]
样本| 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 |
CREATE TABLE mytable(
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);
SP 是预测,QOH 是当前库存,CCBP 是供应
我需要的 YR=42019 季度输出是(总 QOH+Q4 FY 19 CCBP)-Q4 FY 19 SP
然后对于 Yr=12020 季度,我需要期末库存(先前计算的输出)+(Q1 FY 20 CCBP)-Q1 FY 20 SP
以此类推,直到 QuarterYr=22021
输出需要采用相同的格式,即 Full Part、QuartrYr、Name='Ending Inventory'、Value
| 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 |
我假设这需要 recursion/for 循环才能获得所需的输出。 将不胜感激对完成这项工作的任何帮助。
在 SQL 服务器 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
关于不同的通用 Table 表达式 - CTE
PARSE1/PARSE2:
- 字符串中隐藏了一些关键数据"Name"。
- 我们需要提取数据类型、季度和年份信息(假设 2000 + 两位可用)。
- 我们还计划通过将值乘以负 1 来减去 SP。
枢轴 1:
- 现在我们可以应用我们的分组功能来总结季度部分。
分析 1:
- 使用特殊的总和分析函数,我们可以在按 Quarter_Yr 排序时创建一个 运行 计数。
- 包含一个分区子句以在每个逻辑数据集中创建一个 运行 计数。
决赛 SELECT:
- 提供最终清理查询以根据需要显示数据。
您可以将 ROUND() 替换为 CEILING() 或 FLOOR() 以微调结果。
要检查每个单独的 CTE,您可以将最终的 select 替换为:
- SELECT * 来自 PARSE1
- SELECT * 来自 PARSE2
- SELECT * 来自 PIVOT1
- SELECT * 来自分析 1