这就是表格的呈现方式
SELECT RequestsID, Country, Activity,
[People needed (each day)], [Start date], [End date]
FROM dbo.Requests
会有很多请求,我想总结每天“需要的人”(!),而不是在开始和结束日期之间。
此外,我想按国家/地区分组,并且可以设置我想要获取数据的日期。
对于需要的人(0),有些日子可能是空的,但无论如何都应该提供日期。 请注意,可能有多个请求指出相同的日期和相同的国家/地区 - 但活动是不同的。
查询应该是(好吧,你可以看到它不是SQL,只是试图显示逻辑)
From Requests,
show Country and SUM 'People needed'
where (column not in Requests table-Date) is a Date (will be
a number of dates, I want to set the scope by a Start and End date)
and Requests.Country is @Country
(and the Date(s) above of course is between the Requests Start date and End date...)
And from (a non existing table...?) show Date
Group by Country
我希望看到类似的内容:
Date Country People needed
06/01/2010 Nigeria 34 // this might be from three different Requests, all pointing out Nigeria. People needed might be (30+1+3 = 34)
06/02/2010 Nigeria 10
06/03/2010 Nigeria 0
06/04/2010 Nigeria 1
06/05/2010 Nigeria 134
06/01/2010 China 2
06/02/2010 China 0
06/03/2010 China 14
06/04/2010 China 23
06/05/2010 China 33
06/01/2010 Chile 3
06/02/2010 Chile 4
06/03/2010 Chile 0
06/04/2010 Chile 0
06/05/2010 Chile 19
你会怎么做?
注意: 我想看一些示例代码,开始: - )
答案 0 :(得分:2)
通常情况下,我会使用所有日期的计数器或数据透视表,然后根据该范围之间的日期加入。
类似于discussed here的技术。
答案 1 :(得分:2)
这样的事情?
select d.Date, c.Country, sum(People) as PeopleNeeded
from Dates d left join Requests r on d.Date between r.Start and r.End
group by d.Date, c.Country
其中日期包含适当的日期范围,如Cade Roux的答案
答案 2 :(得分:2)
通常情况下,我建议使用一个包含日期顺序列表的静态日历表。但是,使用Cade Roux生成日历表的聪明方法,您可以使用以下内容:
;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);
现在,如果您希望在国家/地区进行过滤,以便返回的唯一天数是具有数据的给定国家/地区,那么您只需将左连接更改为内连接。
<强> ADDITION 强>
从评论中,要求向所有国家/地区显示他们是否有请求。为此,您需要交叉连接到Countries表:
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);