SQL Server 查询中的逻辑问题

问题描述 投票:0回答:1

我有一个年份大师,其值为2019年至2023年。对于每一年,我都创建了2019年至2019年、2019年至2020年、2019年至2021年、2019年至2022年、2019年至2023年的范围。因为我想添加每年

NetValue 
根据项目到明年
enddate

  1. 我想
    SUM()
    在每个项目的
    NetValue
    上,就好像任何项目在2019年开始并在2019年结束,那么应该只在那一年添加。
  2. 如果项目于 2019 年开始但于 2022 年结束,那么其净值应包括 2019 年、2021 年和 2022 年。
  3. 如果项目于 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
sql sql-server select date-range
1个回答
0
投票

这是您要找的吗? (注:我稍微修改了你的 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

*/
© www.soinside.com 2019 - 2024. All rights reserved.