Сначала создайте это полезное представление Tally Table
/****** Object: View [dbo].[cteTally] Script Date: 10/06/2019 11:02:06 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
GO
Затем вы можете сгенерировать список дат, о которых вы спрашиваете, вот так (этот запрос ниже для демонстрации, а не для окончательного кодирования)
Declare @Start as date = '20170101';
Declare @End as date = '20190601';
SELECT dateadd(day, N-1,@Start) aDate from [dbo].[cteTally] WHERE dateadd(day, N-1,@Start) <= @End;
Теперь мы можем расширить это, чтобы подсчитать записи, в которых есть совпадение диапазона дат
SELECT Y.City, DQ.aDate, Count(Y.City) as DayCountForCity FROM (SELECT dateadd(day, N-1,@Start) aDate from [dbo].[cteTally] WHERE dateadd(day, N-1,@Start) <= @End) DQ
LEFT JOIN YourTable Y ON DQ.adate BETWEEN Y.Start_Date AND Y.End_Date
GRoup By Y.City, DQ.adate
Попробуйте сделать это с вашей заданной тестовой таблицей
Declare @Start as date = '20170101';
Declare @End as date = '20450601';
SELECT * FROM (SELECT Y.City, DQ.aDate, Count(Y.City) as DayCountForCity FROM (SELECT dateadd(day, N-1,@Start) aDate from [dbo].[cteTally] WHERE dateadd(day, N-1,@Start) <= @End) DQ
LEFT JOIN Table1 Y ON DQ.adate BETWEEN Y.Start_Date AND Y.End_Date
GRoup By Y.City, DQ.adate) Q1 WHERE Q1.city is not null
order by city, adate