我有下表
<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9UOXRQVi5wbmcifQ==” alt =“在此处输入图像描述”>
第一列是按日期DESC排序的交易日期。第二列是每个交易的二进制状态,可以为0或1。第三列是最小日期与每个日期相比的datediff。产生该表的代码是这样的
DECLARE @date DATE
SELECT @Date = MIN(CONVERT(DATE,Transaction_Created)) FROM #dates
SELECT CONVERT(DATE,Transaction_Created) AS Date
, MAX(Is_Deposit) AS Is_Deposit
, DATEDIFF(dd,@Date,CONVERT(DATE,Transaction_Created)) AS Datedif
FROM #DATES
GROUP BY CONVERT(DATE,Transaction_Created)
order by 1 desc
我的问题是,当is_Deposit = 1时,我需要为DATEDIFF重置种子,而IS_Deposit = 1的日期成为我的新MIN日期,依此类推,对于表中找到的每个IS_Deposit = 1,依此类推。例如,从2015-12-04到2015-12-16,一切正常。但是在746 2015-12-17行中,我希望再次设为1而不是13,因为我们已经达到下一个IS_Deposit = 1且必须重新设置。
现在的结果集:
Date Is_Deposit Datedif
2016-02-12 0 70
2016-02-11 0 69
2016-02-10 0 68
2016-02-09 0 67
2016-02-08 0 66
2016-02-07 0 65
2016-02-06 0 64
2016-02-05 0 63
2016-02-04 0 62
2016-02-03 0 61
2016-02-02 0 60
2016-02-01 0 59
2016-01-31 0 58
2016-01-30 0 57
2016-01-29 0 56
2016-01-28 0 55
2016-01-27 0 54
2016-01-26 0 53
2016-01-25 0 52
2016-01-24 0 51
2016-01-23 0 50
2016-01-22 0 49
2016-01-21 0 48
2016-01-20 1 47
2016-01-17 0 44
2016-01-16 0 43
2016-01-15 0 42
2016-01-14 0 41
2016-01-13 0 40
2016-01-12 0 39
2016-01-11 0 38
2016-01-10 0 37
2016-01-09 0 36
2016-01-08 0 35
2016-01-07 0 34
2016-01-06 0 33
2016-01-05 0 32
2016-01-04 0 31
2016-01-03 0 30
2016-01-02 0 29
2016-01-01 0 28
2015-12-31 0 27
2015-12-30 0 26
2015-12-29 0 25
2015-12-28 0 24
2015-12-27 0 23
2015-12-26 0 22
2015-12-25 1 21
2015-12-20 0 16
2015-12-19 0 15
2015-12-18 0 14
2015-12-17 0 13
2015-12-16 1 12
2015-12-14 0 10
2015-12-13 0 9
2015-12-12 0 8
2015-12-11 0 7
2015-12-10 0 6
2015-12-09 0 5
2015-12-08 0 4
2015-12-07 0 3
2015-12-05 0 1
2015-12-04 1 0
需要结果集:
2016-02-12 0 23
2016-02-11 0 22
2016-02-10 0 21
2016-02-09 0 20
2016-02-08 0 19
2016-02-07 0 18
2016-02-06 0 17
2016-02-05 0 16
2016-02-04 0 15
2016-02-03 0 14
2016-02-02 0 13
2016-02-01 0 12
2016-01-31 0 11
2016-01-30 0 10
2016-01-29 0 9
2016-01-28 0 8
2016-01-27 0 7
2016-01-26 0 6
2016-01-25 0 5
2016-01-24 0 4
2016-01-23 0 3
2016-01-22 0 2
2016-01-21 0 1
2016-01-20 1 26
2016-01-17 0 23
2016-01-16 0 22
2016-01-15 0 21
2016-01-14 0 20
2016-01-13 0 19
2016-01-12 0 18
2016-01-11 0 17
2016-01-10 0 16
2016-01-09 0 15
2016-01-08 0 14
2016-01-07 0 13
2016-01-06 0 12
2016-01-05 0 11
2016-01-04 0 10
2016-01-03 0 9
2016-01-02 0 8
2016-01-01 0 7
2015-12-31 0 6
2015-12-30 0 5
2015-12-29 0 4
2015-12-28 0 3
2015-12-27 0 2
2015-12-26 0 1
2015-12-25 1 9
2015-12-20 0 4
2015-12-19 0 3
2015-12-18 0 2
2015-12-17 0 1
2015-12-16 1 12
2015-12-14 0 10
2015-12-13 0 9
2015-12-12 0 8
2015-12-11 0 7
2015-12-10 0 6
2015-12-09 0 5
2015-12-08 0 4
2015-12-07 0 3
2015-12-05 0 1
2015-12-04 1 0
您可以通过几个窗口功能来做到这一点。首先是运行总计以构建累积序列ID,然后在每个序列中挑选出最小值:
With
DatesSequence AS
(
SELECT Date,Is_Deposit
, SUM(Is_Deposit) OVER(ORDER BY Date DESC) AS Sequence
FROM #Dates
)
SELECT
Date
,Is_Deposit
, DATEDIFF(day,
MIN(Date) OVER (PARTITION BY Sequence),
Date) + 1 AS DateDif
FROM DatesSequence
简单的子查询可以解决此问题。首先,创建并填充示例表(请在您将来的问题中为我们保存此步骤):
DECLARE @T AS TABLE
(
Date date,
Is_Deposit bit,
Datedif int
);
INSERT INTO @T (Date, Is_Deposit, Datedif) VALUES
('2016-02-12', 0, 70),
('2016-02-11', 0, 69),
('2016-02-10', 0, 68),
('2016-02-09', 0, 67),
('2016-02-08', 0, 66),
('2016-02-07', 0, 65),
('2016-02-06', 0, 64),
('2016-02-05', 0, 63),
('2016-02-04', 0, 62),
('2016-02-03', 0, 61),
('2016-02-02', 0, 60),
('2016-02-01', 0, 59),
('2016-01-31', 0, 58),
('2016-01-30', 0, 57),
('2016-01-29', 0, 56),
('2016-01-28', 0, 55),
('2016-01-27', 0, 54),
('2016-01-26', 0, 53),
('2016-01-25', 0, 52),
('2016-01-24', 0, 51),
('2016-01-23', 0, 50),
('2016-01-22', 0, 49),
('2016-01-21', 0, 48),
('2016-01-20', 1, 47),
('2016-01-17', 0, 44),
('2016-01-16', 0, 43),
('2016-01-15', 0, 42),
('2016-01-14', 0, 41),
('2016-01-13', 0, 40),
('2016-01-12', 0, 39),
('2016-01-11', 0, 38),
('2016-01-10', 0, 37),
('2016-01-09', 0, 36),
('2016-01-08', 0, 35),
('2016-01-07', 0, 34),
('2016-01-06', 0, 33),
('2016-01-05', 0, 32),
('2016-01-04', 0, 31),
('2016-01-03', 0, 30),
('2016-01-02', 0, 29),
('2016-01-01', 0, 28),
('2015-12-31', 0, 27),
('2015-12-30', 0, 26),
('2015-12-29', 0, 25),
('2015-12-28', 0, 24),
('2015-12-27', 0, 23),
('2015-12-26', 0, 22),
('2015-12-25', 1, 21),
('2015-12-20', 0, 16),
('2015-12-19', 0, 15),
('2015-12-18', 0, 14),
('2015-12-17', 0, 13),
('2015-12-16', 1, 12),
('2015-12-14', 0, 10),
('2015-12-13', 0, 9 ),
('2015-12-12', 0, 8 ),
('2015-12-11', 0, 7 ),
('2015-12-10', 0, 6 ),
('2015-12-09', 0, 5 ),
('2015-12-08', 0, 4 ),
('2015-12-07', 0, 3 ),
('2015-12-05', 0, 1 ),
('2015-12-04', 1, 0 );
查询:
SELECT Date
, Is_Deposit
, DATEDIFF(
DAY,
(
SELECT TOP 1 Date
FROM @T AS t1
WHERE t1.Date <= t0.Date
AND Is_Deposit = 1
),
Date
) As Datedif
FROM @T As t0
结果:
Date Is_Deposit Datedif
2016-02-12 0 23
2016-02-11 0 22
2016-02-10 0 21
2016-02-09 0 20
2016-02-08 0 19
2016-02-07 0 18
2016-02-06 0 17
2016-02-05 0 16
2016-02-04 0 15
2016-02-03 0 14
2016-02-02 0 13
2016-02-01 0 12
2016-01-31 0 11
2016-01-30 0 10
2016-01-29 0 9
2016-01-28 0 8
2016-01-27 0 7
2016-01-26 0 6
2016-01-25 0 5
2016-01-24 0 4
2016-01-23 0 3
2016-01-22 0 2
2016-01-21 0 1
2016-01-20 1 0
2016-01-17 0 23
2016-01-16 0 22
2016-01-15 0 21
2016-01-14 0 20
2016-01-13 0 19
2016-01-12 0 18
2016-01-11 0 17
2016-01-10 0 16
2016-01-09 0 15
2016-01-08 0 14
2016-01-07 0 13
2016-01-06 0 12
2016-01-05 0 11
2016-01-04 0 10
2016-01-03 0 9
2016-01-02 0 8
2016-01-01 0 7
2015-12-31 0 6
2015-12-30 0 5
2015-12-29 0 4
2015-12-28 0 3
2015-12-27 0 2
2015-12-26 0 1
2015-12-25 1 0
2015-12-20 0 4
2015-12-19 0 3
2015-12-18 0 2
2015-12-17 0 1
2015-12-16 1 0
2015-12-14 0 10
2015-12-13 0 9
2015-12-12 0 8
2015-12-11 0 7
2015-12-10 0 6
2015-12-09 0 5
2015-12-08 0 4
2015-12-07 0 3
2015-12-05 0 1
2015-12-04 1 0
如果要更新表,可以将查询更改为cte并像这样进行更新:
WITH CTE AS
(
SELECT Date
, Is_Deposit
, Datedif
, DATEDIFF(
DAY,
(
SELECT TOP 1 Date
FROM @T AS t1
WHERE t1.Date <= t0.Date
AND Is_Deposit = 1
),
Date
) As NewDatedif
FROM @T As t0
)
UPDATE CTE
SET dateDif = NewDateDif;
我认为您可以只使用累积条件max()
。我无法确定是否确实需要聚合,因此这可以满足您的要求:
SELECT Date, Is_Deposit,
COALESCE(DATEDIFF(day,
date,
MAX(CASE WHEN Is_Deposit = 1 THEN DATE END) OVER
(ORDER BY Date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)
), 0
)
FROM #Dates