我有一个临时表,其中包含交易,日期和交易量。我需要以动态方式计算生效日期之间的日期。同时,这也使情况变得复杂,每笔交易的第一个都是过去的交易,但是代表当前交易量。因此,对于该行,我需要返回从今天到该交易的下一个生效日期的天数。此外,在每笔交易的最后生效日期,我必须运行一个子查询以从另一个临时表中获取合同结束日期。
临时表的样本和所需的样本返回: Sample
答案 0 :(得分:0)
这是一个探索的选择。
基本上,每条记录的要求是:
然后,您可以根据这些值评估并确定天数。
这是一个临时表和一些示例数据:
CREATE TABLE #Deal
(
[Row_ID] INT
, [Deal_ID] BIGINT
, [EffectiveDate] DATE
, [Volume] BIGINT
);
INSERT INTO #Deal (
[Row_ID]
, [Deal_ID]
, [EffectiveDate]
, [Volume]
)
VALUES ( 1, 1479209, '2018-11-01', 5203 )
, ( 2, 1479209, '2019-03-01', 2727 )
, ( 3, 1479209, '2019-04-01', 1615 )
, ( 4, 1479209, '2019-06-01', 1325 )
, ( 5, 1598451, '2018-12-01', 2000 )
, ( 6, 1598451, '2019-04-01', 4000 )
, ( 7, 1598451, '2019-08-01', 4000 );
以下是使用LAG()和子查询的示例查询:
SELECT *
-- LAG here partitioned by the Deal_ID, will return NULL if first record.
, LAG([dl].[EffectiveDate], 1, NULL) OVER ( PARTITION BY [dl].[Deal_ID]
ORDER BY [dl].[EffectiveDate]
) AS [PreviousRowEffectiveData]
--Sub query to get min EffectiveDate that is greater than today
, (
SELECT MIN([dl1].[EffectiveDate])
FROM #Deal [dl1]
WHERE [dl1].[Deal_ID] = [dl].[Deal_ID]
AND [dl1].[EffectiveDate] > GETDATE()
) AS [NextEffectiveDateAfterToday]
FROM #Deal [dl]
为您提供这些结果:
Row_ID Deal_ID EffectiveDate Volume PreviousRowEffectiveData NextEffectiveDateAfterToday
----------- -------------------- ------------- -------------------- ------------------------ ---------------------------
1 1479209 2018-11-01 5203 NULL 2019-03-01
2 1479209 2019-03-01 2727 2018-11-01 2019-03-01
3 1479209 2019-04-01 1615 2019-03-01 2019-03-01
4 1479209 2019-06-01 1325 2019-04-01 2019-03-01
5 1598451 2018-12-01 2000 NULL 2019-04-01
6 1598451 2019-04-01 4000 2018-12-01 2019-04-01
7 1598451 2019-08-01 4000 2019-04-01 2019-04-01
现在,如果我正确理解的话,我们可以在子查询中使用它,然后为DAYS实施业务规则:
查询示例:
SELECT *
--Case statement, if previousrow null(first record) difference in days of datday and NextEfectiveDateAfterToday
--Else we will do the difference in days of previousrow and this rows effective date.
, CASE WHEN [Deal].[PreviousRowEffectiveData] IS NULL THEN DATEDIFF(DAY, GETDATE(), [Deal].[NextEffectiveDateAfterToday])
ELSE DATEDIFF(DAY, [Deal].[PreviousRowEffectiveData], [Deal].[EffectiveDate])
END AS [DAYS]
FROM (
SELECT *
-- LAG here partioned by the Deal_ID, we'l return NULL if first record.
, LAG([dl].[EffectiveDate], 1, NULL) OVER ( PARTITION BY [dl].[Deal_ID]
ORDER BY [dl].[EffectiveDate]
) AS [PreviousRowEffectiveData]
--Sub query to get min EffectiveDate that is greater than today
, (
SELECT MIN([dl1].[EffectiveDate])
FROM #Deal [dl1]
WHERE [dl1].[Deal_ID] = [dl].[Deal_ID]
AND [dl1].[EffectiveDate] > GETDATE()
) AS [NextEffectiveDateAfterToday]
FROM #Deal [dl]
) AS [Deal];
为我们提供以下最终结果:
Row_ID Deal_ID EffectiveDate Volume PreviousRowEffectiveData NextEffectiveDateAfterToday DAYS
----------- -------------------- ------------- -------------------- ------------------------ --------------------------- -----------
1 1479209 2018-11-01 5203 NULL 2019-03-01 14
2 1479209 2019-03-01 2727 2018-11-01 2019-03-01 120
3 1479209 2019-04-01 1615 2019-03-01 2019-03-01 31
4 1479209 2019-06-01 1325 2019-04-01 2019-03-01 61
5 1598451 2018-12-01 2000 NULL 2019-04-01 45
6 1598451 2019-04-01 4000 2018-12-01 2019-04-01 121
7 1598451 2019-08-01 4000 2019-04-01 2019-04-01 122