在社区的大量帮助下,我已经能够创建一个查询,如果没有交易,该查询会自动为项目添加新行,并包含前一行的累积数字。不幸的是我遇到了我想改变的事情。如果期间之间的期间内没有交易,则这些期间将丢失。我也想填补这些。
示例:项目 12345 GL:
项目 | 数量 | 时期 |
---|---|---|
12345 | 10 | 202001 |
12345 | 10 | 202002 |
12345 | 10 | 202003 |
12345 | 10 | 202004 |
12345 | 10 | 202005 |
12345 | 10 | 202006 |
12345 | 10 | 202009年 |
我的代码如下:
DECLARE @d date = DATEFROMPARTS(YEAR(getdate()), MONTH(getdate()), 1);
;WITH src AS -- mostly your existing query
(
SELECT project,
period,
rn = ROW_NUMBER() OVER
(PARTITION BY project ORDER BY period DESC),
amount = SUM(SUM(amount)) OVER
(PARTITION BY project ORDER BY period
ROWS UNBOUNDED PRECEDING)
FROM dbo.GLProject
GROUP BY project, period
),
recur AS
(
SELECT project, period = DATEADD(MONTH, 1, period), amount
FROM src
WHERE rn = 1 AND period < @d
UNION ALL
SELECT project, DATEADD(MONTH, 1, period), amount
FROM recur WHERE period < @d
)
SELECT project, amount, period = CONVERT(char(6), period, 112)
FROM src
UNION ALL
SELECT project, amount, period = CONVERT(char(6), period, 112)
FROM recur
ORDER BY project, period;
Run Code Online (Sandbox Code Playgroud)
我希望它也能填补缺失的时期 202007 和 202008。像这样:
项目 | 数量 | 时期 |
---|---|---|
12345 | 10 | 202001 |
12345 | 20 | 202002 |
12345 | 30 | 202003 |
12345 | 40 | 202004 |
12345 | 50 | 202005 |
12345 | 60 | 202006 |
12345 | 60 | 202007 |
12345 | 60 | 202008 |
12345 | 70 | 202009年 |
12345 | 70 | 202010年 |
12345 | 70 | 202011 |
12345 | 70 | 202012年 |
12345 | 70 | 202101 |
12345 | 70 | 202102 |
12345 | 70 | 202103 |
12345 | 70 | 202104 |
12345 | 70 | 202105 |
12345 | 70 | 202106 |
12345 | 70 | 202107 |
12345 | 70 | 202108 |
12345 | 70 | 202109 |
关于添加到我的查询中以解决此问题的任何想法?
在这里进行测试的小提琴:https://dbfiddle.uk/? rdbms=sqlserver_2019&fiddle=615712cf89113c3a912268ed603fd2b4
非常感谢!
您可能不会相信我,但添加填补缺失空白的要求实际上推动了一个更简单的解决方案。
DECLARE @d date = DATEFROMPARTS(YEAR(getdate()), MONTH(getdate()), 1);
;WITH total_range AS
(
SELECT project, period = MIN(period)
FROM dbo.GLProject
GROUP BY project
UNION ALL
SELECT project, DATEADD(MONTH, 1, period)
FROM total_range
WHERE period < @d
)
SELECT
tr.project,
amount = SUM(COALESCE(p.amount,0)) OVER (
PARTITION BY tr.project ORDER BY tr.period
-- ROWS UNBOUNDED PRECEDING -- not strictly necessary here
),
period = CONVERT(char(6), tr.period, 112)
FROM total_range AS tr
LEFT OUTER JOIN dbo.GLProject AS p
ON tr.project = p.project
AND tr.period = p.period;
Run Code Online (Sandbox Code Playgroud)