I have a list of dates, with occasional events that correspond to start and stop dates for periods, and I want to flip a bit switch for all dates which occur between start and stop.
Example:
DateList = (
'2001-01-01',
'2001-01-02',
'2001-01-03',
'2001-01-04',
'2001-01-05',
'2001-01-06',
'2001-01-07',
'2001-01-08',
'2001-01-09',
'2001-01-10',
'2001-01-011')
Events = (
('2001-01-05', 'on')
('2001-01-08', 'off'))
(Obviously just a pseudocode example).
Is there a way to join these two tables without using a cursor and get the following result:
Result (Date, Event, Bit) = (
('2001-01-01', NULL, 0)
('2001-01-02', NULL, 0)
('2001-01-03', NULL, 0)
('2001-01-04', NULL, 0)
('2001-01-05', 'on', 1)
('2001-01-06', NULL, 1)
('2001-01-07', NULL, 1)
('2001-01-08', 'off', 0)
('2001-01-09', NULL, 0)
('2001-01-10', NULL, 0)
('2001-01-11', NULL, 0)
I hope this makes sense. Obviously would be easy with a cursor, but is there another way using only joins?
Thanks everyone for your time.
CodePudding user response:
I think this will help you
CREATE TABLE DateList(Period date) ;
CREATE TABLE EVENTS (Period date, Event varchar(5));
INSERT INTO Events(Period, Event)
VALUES ('2001-01-05', 'on'),
('2001-01-08', 'off');
INSERT INTO DateList(Period)
VALUES ('2001-01-01'),
('2001-01-02'),
('2001-01-03'),
('2001-01-04'),
('2001-01-05'),
('2001-01-06'),
('2001-01-07'),
('2001-01-08'),
('2001-01-09'),
('2001-01-10'),
('2001-01-11');
SELECT d.Period AS
START , j.Event,
CASE
WHEN e.Event='on' THEN 1
ELSE 0
END [Bit]
FROM DateList d
LEFT JOIN EVENTS j ON j.Period=d.Period
LEFT JOIN
(SELECT Period AS PeriodStart,
isnull(dateadd(DAY, -1, lead(Period, 1) over(
ORDER BY Period)), Period) PeriodEnd,
Event
FROM EVENTS) E ON d.Period BETWEEN e.PeriodStart AND e.PeriodEnd;