SQL重叠日期范围

时间:2013-07-17 19:24:33

标签: sql sql-server

我有一个包含3个字段“开始日期”和“结束日期”以及“分配%”的表格。我需要找出此表中距离当前日期3个月内的所有记录,

并且(这个很棘手)只有具有重叠日期范围的记录,其中Sum(Allocation%)> 100。

请帮我提出一个问题。

这是表格架构。

Table (ResourceAssignment)
   - ResourceAssignmentID (PK)
   - ResourceID (FK)
   - Assigned To (FK)
   - Start Date
   - End Date
   - Allocation %

我基本上需要在一定时间内(从当天到3个月)找到所有分配的资源。

提前致谢!

4 个答案:

答案 0 :(得分:1)

不确定这是否是你所追求的,但这会显示所有ResourceID,其分配超过100%,其开始或结束日期在过去3个月内:

SELECT ResourceID 
FROM ResourceAssignment
WHERE StartDate BETWEEN DATEADD(month,-3,GETDATE())  AND GETDATE()
  OR EndDate BETWEEN DATEADD(month,-3,GETDATE())  AND GETDATE()
GROUP BY ResourceID 
HAVING SUM([Allocation %]) > 100

答案 1 :(得分:1)

您有两种常规解决方案。哪个最好取决于ResourceAllocation的大小,冲突的频率以及您打算如何呈现数据。

解决方案1:在接下来的3个月内制作一个日期列表并加入其中以确定哪​​些日期已过度分配

WITH
  datelist AS (
    SELECT CAST(GETDATE() AS date) [d] UNION ALL SELECT DATEADD(day,1,[d]) FROM datelist WHERE [d] < DATEADD(month,3,GETDATE())
  ),
  allocations AS (
    SELECT *,SUM([Allocation %]) OVER(PARTITION BY [ResourceID],[d]) AS [Total Allocation %]
    FROM datelist
    INNER JOIN ResourceAssignment ON ([d] BETWEEN [Start Date] AND [End Date])
  )
SELECT *
FROM allocations
WHERE [Total Allocation %] >= 100

解决方案2:在ResourceAssignment上使用带有自联接的范围冲突查询

SELECT *
FROM (
  SELECT
    t1.*,SUM(t1.[Allocation %]) OVER(PARTITION BY t1.[ResourceID]) AS [Total Allocation %]
  FROM ResourceAssignment t1
  INNER JOIN ResourceAssignment t2 ON (
    t1.[ResourceID] = t2.[ResourceID] AND
    t1.[ResourceAssignmentID] <> t2.[ResourceAssignmentID] AND
    t1.[Start Date] < t2.[End Date] AND
    t2.[Start Date] < t1.[End Date]
  )
  WHERE
    t1.[Start Date] <= CAST(GETDATE()+30 as date) AND
    t2.[Start Date] <= CAST(GETDATE()+30 as date) AND
    t1.[End Date] > CAST(GETDATE() as date) AND
    t2.[End Date] > CAST(GETDATE() as date)
) t
WHERE [Total Allocation %] >= 100

答案 2 :(得分:0)

我认为这是你想要实现的目标:

SELECT SUM(Allocation), ResourceID
FROM ResourceAssignment
WHERE EndDate BETWEEN GETDATE() AND  DATEADD(m,3,GETDATE())
GROUP BY ResourceID
HAVING SUM(Allocation) > 100

答案 3 :(得分:0)

我假设开始日期和结束日期的格式为日期时间或日期。

我不确定您是否在尝试确定开始日期记录是否属于过去3个月或结束日期记录。

此外,您还需要一个限制来确定总和(分配百分比)。你想要总结什么独特的记录。既然你想要Sum Allocation%然后只选择那些大于100的那个,那么你必须弄清楚要拉出哪些来总和。

您需要使用With语句或创建子“表”(查询)来完成此操作,这些子表可以分阶段提取所需的信息。我将介绍子查询语句。

为Sql-Server 2008 R2编写

首先选择过去3个月内的数据

Select ResourceAssignmentID, ResourceID, [Assigned To], [Allocation %]
From ResourceAssignment
Where [Start Date] >= dateadd(Month,-3,Now)

然后使用此数据,您需要对分配百分比求和。 (我假设基于2个外键的组合)

Select Query1.ResourceID, Query1.[Assigned To], sum(Query1.[Allocation %]) as Sumofallocation
From
(Select ResourceAssignmentID, ResourceID, [Assigned To], [Allocation %]
From ResourceAssignment
Where [Start Date] >= dateadd(Month,-3,Now)) Query1
Group By Query1.ResourceID, Query1.[Assigned To], sum(Query1.[Allocation %]) 

您可以在群组之前添加Where语句,以过滤掉&gt; 100要求,但我只想添加另一个Select语句将其全部拉出来

Select * From
(Select Query1.ResourceID, Query1.[Assigned To], sum(Query1.[Allocation %]) as Sumofallocation
From
(Select ResourceAssignmentID, ResourceID, [Assigned To], [Allocation %]
From ResourceAssignment
Where [Start Date] >= dateadd(Month,-3,Now)) Query1
Group By Query1.ResourceID, Query1.[Assigned To], sum(Query1.[Allocation %]) 
) Query2
Where Query2.Sumofallocation > 100

此外,您似乎正在开发项目管理类型计划。 Microsoft Project不会工作吗?您可以在任何您想要的时间范围内看到谁分配了。如果你有多个项目,你可以将它们合并到一个大的Project文件中,然后就这样看......

无论如何,我希望这会有所帮助。 SQL可能并不完美,但它应该指向一个可行的方向。