Zwykle sugerowałbym posiadanie statycznej tabeli kalendarza, która zawiera sekwencyjną listę dat. Jednak używając sprytnego podejścia Cade Roux do generowania tabeli kalendarza, otrzymasz coś takiego:
;With Calendar As
(
Select Cast(Floor(Cast(@StartDate As float)) As datetime) As [Date]
Union All
Select DateAdd(d, 1, [Date])
From Calendar
Where DateAdd(d, 1, [Date]) < @EndDate
)
Select C.[Date], R.Country, Sum(R.PeopleNeeded)
From Calendar As C
Left Join Requests As R
On C.[Date] Between R.[Start Date] And R.[End Date]
And ( @Country Is Null Or R.Country = @Country )
Group By C.[Date], R.Country
Option (MAXRECURSION 0);
Teraz, jeśli chcesz filtrować według kraju w taki sposób, że zwracane są tylko te dni dla danego kraju, w których są dane, wystarczy zmienić sprzężenie lewe na sprzężenie wewnętrzne.
DODAT
Na podstawie komentarzy poproszono o pokazanie wszystkim krajom, czy mają wniosek, czy nie. Aby to zrobić, musisz połączyć się krzyżowo z tabelą Kraje:
With Calendar As
(
Select Cast(Floor(Cast(@StartDate As float)) As datetime) As [Date]
Union All
Select DateAdd(d, 1, [Date])
From Calendar
Where DateAdd(d, 1, [Date]) < @EndDate
)
Select C.[Date], C2.Country, Sum(R.PeopleNeeded)
From Calendar As C
Cross Join Countries As C2
Left Join Requests As R
On C.[Date] Between R.[Start Date] And R.[End Date]
And R.CountryId = C2.CountryId
Group By C.[Date], C2.Country
Option (MAXRECURSION 0);