我有一个年份大师,其值为2019年至2023年。对于每一年,我都创建了2019年至2019年、2019年至2020年、2019年至2021年、2019年至2022年、2019年至2023年的范围。因为我想添加每年
NetValue
根据项目到明年 enddate
。
SUM()
在每个项目的NetValue
上,就好像任何项目在2019年开始并在2019年结束,那么应该只在那一年添加。enddate
为空,则意味着项目将持续到最大年份值。那么它的净值应该在2019年、2020年、2021年、2022年、2023年添加。请提供一些想法来实现这个逻辑。到目前为止我尝试过的如下:
;WITH YearRanges AS
(
SELECT 2019 AS StartYear, 2019 AS EndYear
UNION ALL
SELECT StartYear, EndYear + 1
FROM YearRanges
WHERE EndYear + 1 <= 2023
)
SELECT
YR.EndYear AS Year,
SUM(CASE
WHEN YEAR(T.projectstartdate) = YR.EndYear THEN cast(T.NetValue as decimal(18,2))
WHEN YEAR(T.enddate) >= YR.EndYear THEN cast(T.NetValue as decimal(18,2))
ELSE 0
END) AS TotalAmount
FROM
YearRanges YR
JOIN
TrackerMainEntry T ON YEAR(T.projectstartdate) >= YR.StartYear
GROUP BY
YR.EndYear
OPTION (MAXRECURSION 0);
尝试过:我尝试过根据指定范围进行选择。
结果:我每年得到的值都是错误的。我也应用了
Cross Join
但仍然给我错误的值。
下面是我实际上必须实现的逻辑
SELECT
NetValue, projectstartdate, enddate
FROM
[TrackerMainEntry]
WHERE
YEAR(projectstartdate) IN (2019)
UNION
SELECT
NetValue, projectstartdate, enddate
FROM
[TrackerMainEntry]
WHERE
YEAR(projectstartdate) IN (2019)
AND YEAR(enddate) IS NULL
UNION
SELECT
NetValue, projectstartdate, enddate
FROM
[TrackerMainEntry]
WHERE
YEAR(projectstartdate) IN (2019)
AND YEAR(enddate) = 2022
UNION
SELECT
NetValue, projectstartdate, enddate
FROM
[TrackerMainEntry]
WHERE
YEAR(projectstartdate) IN (2020)
样本数据:
CREATE TABLE [dbo].[SampleData]
(
[productname] [varchar](100) NULL,
[NetValue] [varchar](100) NULL,
[ProjectStartDate] [date] NULL,
[EndDate] [date] NULL);
GO
INSERT [dbo].[SampleData] ([productname], [NetValue], [ProjectStartDate], [EndDate])
VALUES ('Project_22', '-11224.68', CAST('2020-03-01' AS Date), CAST('2021-12-15' AS Date)),
('Project_64', '261706.4', CAST('2019-11-01' AS Date), CAST('2022-08-18' AS Date)),
('Project_64', '21309.44', CAST('2021-01-01' AS Date), CAST('2022-08-18' AS Date)),
('Project_4', '3057.2', CAST('2020-03-01' AS Date), NULL),
('Project_39', '88298.272', CAST('2020-07-01' AS Date), CAST('2022-08-08' AS Date)),
('Project_33', '256230.16', CAST('2019-12-01' AS Date), CAST('2022-08-30' AS Date)),
('Project_10', '219442.44', CAST('2021-10-01' AS Date), CAST('2021-11-26' AS Date)),
('Project_61', '-18707.8', CAST('2021-06-01' AS Date), NULL),
('Project_44', '40444.52', CAST('2021-10-01' AS Date), CAST('2022-09-01' AS Date)),
('Project_37', '989082', CAST('2021-11-01' AS Date), CAST('2021-12-15' AS Date)),
('Project_62', '113845.344', CAST('2019-01-01' AS Date), NULL),
('Project_63', '143278.56', CAST('2021-05-01' AS Date), CAST('2022-09-15' AS Date)),
('Project_68', '33998.896', CAST('2021-05-01' AS Date), CAST('2022-08-01' AS Date)),
('Project_65', '56889.04', CAST('2020-04-01' AS Date), NULL),
('Project_56', '279507.92', CAST('2020-10-01' AS Date), NULL),
('Project_20', '145405.92', CAST('2022-05-01' AS Date), CAST('2022-05-27' AS Date)),
('Project_60', '365556.16', CAST('2022-08-22' AS Date), CAST('2022-05-27' AS Date)),
('Project_5', '5322.264', CAST('2020-08-01' AS Date), CAST('2022-09-01' AS Date)),
('Project_51', '31690.9', CAST('2020-12-01' AS Date), NULL),
('Project_67', '28117.984', CAST('2021-06-01' AS Date), NULL),
('Project_59', '10735.488', CAST('2021-03-01' AS Date), NULL),
('Project_12', '2974.98', CAST('2022-05-03' AS Date), CAST('2022-05-13' AS Date)),
('Project_29', '18307.36', CAST('2019-09-01' AS Date), NULL),
('Project_47', '147818.38', CAST('2020-09-01' AS Date), NULL),
('Project_2', '-8660.24', CAST('2021-01-01' AS Date), CAST('2021-12-15' AS Date)),
('Project_16', '14490.552', CAST('2020-10-01' AS Date), NULL),
('Project_45', '188519.088', CAST('2021-03-01' AS Date), NULL),
('Project_15', '161817.76', CAST('2021-02-01' AS Date), CAST('2022-09-01' AS Date)),
('Project_55', '39743.344', CAST('2022-01-01' AS Date), CAST('2022-05-30' AS Date)),
('Project_35', '139378.08', CAST('2020-12-01' AS Date), CAST('2022-08-18' AS Date)),
('Project_40', '12552.72', CAST('2021-01-01' AS Date), CAST('2023-10-02' AS Date)),
('Project_43', '9998.896', CAST('2021-07-01' AS Date), CAST('2023-10-02' AS Date)),
('Project_53', '94926.32', CAST('2022-08-01' AS Date), CAST('2022-01-10' AS Date)),
('Project_7', '35094.992', CAST('2021-03-01' AS Date), NULL),
('Project_50', '20534.18', CAST('2021-05-01' AS Date), CAST('2022-09-01' AS Date)),
('Project_8', '674.5', CAST('2020-07-01' AS Date), NULL),
('Project_3', '4380.568', CAST('2019-11-01' AS Date), NULL),
('Project_10', '42712.64', CAST('2022-09-22' AS Date), CAST('2023-10-02' AS Date)),
('Project_33', '129340.44', CAST('2020-10-01' AS Date), NULL),
('Project_33', '119190.2', CAST('2021-01-01' AS Date), NULL),
('Project_33', '102820.46', CAST('2021-10-01' AS Date), NULL),
('Project_33', '150575.48', CAST('2022-09-01' AS Date), NULL),
('Project_23', '55964.16', CAST('2020-06-01' AS Date), NULL),
('Project_21', '-16.32', CAST('2020-08-01' AS Date), NULL),
('Project_6', '-544.66', CAST('2021-02-01' AS Date), NULL),
('Project_31', '-411', CAST('2020-08-01' AS Date), NULL),
('Project_42', '-378.41', CAST('2021-03-01' AS Date), NULL),
('Project_19', '-9460.23', CAST('2020-12-01' AS Date), NULL),
('Project_1', '71573.1', CAST('2021-03-01' AS Date), NULL),
('Project_26', '282114.4', CAST('2020-12-01' AS Date), NULL),
('Project_63', '19964.16', CAST('2022-08-22' AS Date), NULL),
('Project_37', '986980', CAST('2022-05-22' AS Date), CAST('2022-09-15' AS Date)),
('Project_57', '1349', CAST('2021-07-01' AS Date), NULL),
('Project_41', '998.896', CAST('2021-06-01' AS Date), NULL),
('Project_17', '12489.04', CAST('2022-08-22' AS Date), NULL),
('Project_53', '16853.2', CAST('2022-08-01' AS Date), CAST('2022-10-07' AS Date)),
('Project_20', '21003.184', CAST('2022-11-01' AS Date), CAST('2023-02-03' AS Date)),
('Project_37', '15302.56', CAST('2022-10-01' AS Date), NULL),
('Project_28', '60000', CAST('2023-01-01' AS Date), CAST('2022-10-07' AS Date)),
('Project_15', '108967.68', CAST('2022-12-01' AS Date), CAST('2023-02-01' AS Date));
GO
这是您要找的吗? (注:我稍微修改了你的 CTE...)
;WITH YearRanges AS
(
SELECT 2019 AS [PeriodYear]
UNION ALL
SELECT [PeriodYear] + 1
FROM YearRanges
WHERE [PeriodYear] + 1 <= 2023
)
SELECT
yr.[PeriodYear],
SUM(sd.NetValue) AS TotalAmount
FROM YearRanges yr
INNER JOIN dbo.SampleData sd
ON YEAR(sd.ProjectStartDate) <= yr.[PeriodYear]
AND
(
YEAR(sd.EndDate) IS NULL
OR YEAR(sd.EndDate) >= yr.[PeriodYear]
)
GROUP BY yr.[PeriodYear]
ORDER BY yr.[PeriodYear]
/*
Results
-------
PeriodYear TotalAmount
2019 654469.83
2020 1867903.70
2021 4050471.22
2022 4885286.36
2023 2060527.91
*/