I'd handle it like this:
declare @test date = '2021-06-14';
declare @zip varchar(7) = '27520';
declare @routes table (zip varchar(255), monday varchar(255), tuesday varchar(255), wednesday varchar(255), thursday varchar(255), friday varchar(255), saturday varchar(255), sunday varchar(255));
INSERT INTO @routes VALUES
('27520', '1', '0', '1', '0', '1', '0', '0'),
('27523', '1', '1', '0', '1', '1', '0', '0');
declare @nextdays table(vdate date, dow int);
INSERT INTO @nextdays (vdate) VALUES
(DATEADD(dd, 1, @test)),
(DATEADD(dd, 2, @test)),
(DATEADD(dd, 3, @test)),
(DATEADD(dd, 4, @test)),
(DATEADD(dd, 5, @test)),
(DATEADD(dd, 6, @test)),
(DATEADD(dd, 7, @test)),
(DATEADD(dd, 8, @test)),
(DATEADD(dd, 9, @test)),
(DATEADD(dd, 10, @test)),
(DATEADD(dd, 11, @test)),
(DATEADD(dd, 12, @test)),
(DATEADD(dd, 13, @test)),
(DATEADD(dd, 14, @test)),
(DATEADD(dd, 15, @test)),
(DATEADD(dd, 16, @test)),
(DATEADD(dd, 17, @test)),
(DATEADD(dd, 18, @test)),
(DATEADD(dd, 19, @test)),
(DATEADD(dd, 20, @test)),
(DATEADD(dd, 21, @test));
UPDATE @nextdays SET dow = DATEPART(dw, vdate);
WITH cte AS
(SELECT 1 as dow, sunday from @routes WHERE zip = @zip
UNION
SELECT 2 as dow, monday from @routes WHERE zip = @zip
UNION
SELECT 3 as dow, tuesday from @routes WHERE zip = @zip
UNION
SELECT 4 as dow, wednesday from @routes WHERE zip = @zip
UNION
SELECT 5 as dow, thursday from @routes WHERE zip = @zip
UNION
SELECT 6 as dow, friday from @routes WHERE zip = @zip
UNION
SELECT 7 as dow, saturday from @routes WHERE zip = @zip)
SELECT TOP 3 vdate
FROM @nextdays n
INNER JOIN cte c ON n.dow = c.dow AND c.sunday = '1'
ORDER BY n.vdate;
I am inserting 21 dates into the table variable, in case there is only 1 delivery date for a given zip. Obviously if all zips have a minimum of 2 or 3 delivery days you can reduce the amount inserted.
I then do a UNION
instead of an UNPIVOT
, simply because with a limited number of requirements it is a bit easier to understand. Note that the UNION
restricts the SELECT
to the required zip.
One point to note, when doing a UNION
in this fashion, if the column names are different, the name of the resulting column is the name of the column in the first SELECT
in the UNION
. Hence the JOIN
is on c.sunday = '1'.