Date Status Date_Change
----------------------------------------------------------------------------
2019-07-10-15.05.46.918680 A 2019-07-10-15.05.46.934000
2019-07-10-15.05.46.918680 A 2019-07-10-15.05.50.272680
2019-07-10-15.05.46.918680 A 2019-07-10-15.05.50.491680
2019-07-10-15.05.46.918680 B 2019-07-10-15.05.50.740680
2019-07-10-15.05.46.918680 B 2019-07-10-15.05.50.990680
2019-07-10-15.05.46.918680 A 2019-07-15-10.44.54.386680
2019-07-10-15.05.46.918680 A 2019-07-15-10.44.54.837680
2019-07-10-15.05.46.918680 A 2019-07-15-10.45.28.769680
参考上面的数据,我需要状态从A更改为B,C,D等其他日期并再次返回到A的那些Date的数据。
请帮助。我正在使用SQL Server 2008 R2。
我尝试过
select status, min(DATE_CHANGE), max(DATE_CHANGE)
from (select t.*,
(row_number() over (order by DATE_CHANGE) -
row_number() over (partition by status order by DATE_CHANGE)
) as grp
from mytable t
) t
group by status, grp
但是它不起作用。
输出应类似于:-
Date
-----------------------------
2019-07-10-15.05.46.918680...
如果日期的初始状态为“ A”,然后又更改为其他状态,然后再次返回“ A”,则该日期数据应显示为输出。
答案 0 :(得分:0)
我想这就是你想要的
CREATE TABLE #data
(
Date DATETIME2,
Status CHAR(1),
Date_Change DATETIME2
);
INSERT INTO #data(Date, Status, Date_Change)
VALUES
-- positive example - goes from A to B and back to A
('2019-07-10T15:05:46.918680','A','2019-07-10T15:05:46.934000'),
('2019-07-10T15:05:46.918680','A','2019-07-10T15:05:50.272680'),
('2019-07-10T15:05:46.918680','A','2019-07-10T15:05:50.491680'),
('2019-07-10T15:05:46.918680','B','2019-07-10T15:05:50.740680'),
('2019-07-10T15:05:46.918680','B','2019-07-10T15:05:50.990680'),
('2019-07-10T15:05:46.918680','A','2019-07-15T10:44:54.386680'),
('2019-07-10T15:05:46.918680','A','2019-07-15T10:44:54.837680'),
('2019-07-10T15:05:46.918680','A','2019-07-15T10:45:28.769680'),
-- a second positive example - goes from A to B and back to A
('2019-07-10T15:06:46.918680','A','2019-07-10T15:06:46.934000'),
('2019-07-10T15:06:46.918680','B','2019-07-10T15:06:50.740680'),
('2019-07-10T15:06:46.918680','B','2019-07-10T15:06:50.990680'),
('2019-07-10T15:06:46.918680','A','2019-07-15T11:44:54.386680'),
('2019-07-10T15:06:46.918680','A','2019-07-15T11:44:54.837680'),
('2019-07-10T15:06:46.918680','A','2019-07-15T11:45:28.769680'),
-- negative example 1 - always A
('2019-07-10T15:07:46.918680','A','2019-07-10T15:07:46.934000'),
('2019-07-10T15:07:46.918680','A','2019-07-10T15:07:50.272680'),
('2019-07-10T15:07:46.918680','A','2019-07-10T15:07:50.491680'),
('2019-07-10T15:07:46.918680','A','2019-07-10T15:07:50.740680'),
-- negative example 2 - goes from A to B but stays there
('2019-07-10T15:08:46.918680','A','2019-07-10T15:08:46.934000'),
('2019-07-10T15:08:46.918680','A','2019-07-10T15:08:50.272680'),
('2019-07-10T15:08:46.918680','A','2019-07-10T15:08:50.491680'),
('2019-07-10T15:08:46.918680','A','2019-07-10T15:08:50.740680');
-- so I expect 15:05 and 15:06 to be returned, but not 15:07 and 15:08
WITH ranges AS
(
SELECT Date, MIN(Date_Change) MinDate, MAX(Date_Change) MaxDate
FROM #data
WHERE Status = 'A'
GROUP BY Date
)
SELECT DISTINCT #data.Date
FROM #data
INNER JOIN ranges r ON r.Date = #data.Date
WHERE EXISTS (SELECT * FROM #data WHERE Date_Change < MaxDate and Date_Change > MinDate AND Status != 'A')