【问题标题】:Find the most Overlapped days?找到最多重叠的日子?
【发布时间】:2012-04-01 10:57:26
【问题描述】:

我正在尝试编写一个将发出的查询:

最多重叠的日期。

格式为d/m/yyyy

所以这里我有日期范围:

dateStart-----dateEnd

  1/1---7/1                          

         8/1--15/1                   

               16/1------20/1               

         8/1--------------21/1       

                17/1---19/1 

                 18/1--19/1  

这是预期的结果分析:

左边的 2 个常见日期是 8/19/1(出现在 2 个范围内)

右边的 4 个常见日期是 18/119/1(出现在 4 个范围内......并且 4>2 所以它应该获胜。)

想要的结果:

18/1

19/1

它们看起来重叠最多。

编辑

这是日期时间范围的脚本。

DECLARE @t table( dt1 DATETIME , dt2 DATETIME)

INSERT INTO @t
SELECT '20110101','20110107'
UNION ALL
SELECT '20110108','20110115'
UNION ALL
SELECT '20110116','20110120'
UNION ALL
SELECT '20110108','20110121'
UNION ALL
SELECT '20110117','20110119'
UNION ALL
SELECT '20110118','20110119'

【问题讨论】:

  • 如果有一些样本数据就好了。
  • @TimSchmelter 你的意思是插入显示数据的脚本吗?谢谢
  • 是的,这样我们讲的一样,可以比较结果。
  • @TimSchmelter 完成。看我的编辑。谢谢
  • 日期范围是否包含在内?

标签: sql-server sql-server-2008


【解决方案1】:

恐怕这不是您正在寻找的,但也许它对您有帮助(我的时间不多了):

DECLARE @tbl table( startdate DATETIME , enddate DATETIME)

INSERT INTO @tbl
SELECT '20110101','20110107'
UNION ALL
SELECT '20110108','20110115'
UNION ALL
SELECT '20110116','20110120'
UNION ALL
SELECT '20110108','20110121'
UNION ALL
SELECT '20110117','20110119'
UNION ALL
SELECT '20110118','20110119'

;with overlapping_events as(
    select startdate, enddate
       , (select sum(inTimeSpan) 
    from (
       select case when startdate<=events.startdate then 1 else 0 end
         + case when enddate <= events.startdate then -1 else 0 end as inTimeSpan
       from @tbl 
       where startdate <= events.startdate
         or enddate <= events.startdate) as previous
    ) as overlapping
    from @tbl events
)
select oe.* 
from overlapping_events oe 
order by overlapping desc, startdate asc, enddate asc

startdate                     enddate                     overlapping
2011-01-18 00:00:00.000   2011-01-19 00:00:00.000         4
2011-01-17 00:00:00.000   2011-01-19 00:00:00.000         3
2011-01-08 00:00:00.000   2011-01-15 00:00:00.000         2
2011-01-08 00:00:00.000   2011-01-21 00:00:00.000         2
2011-01-16 00:00:00.000   2011-01-20 00:00:00.000         2
2011-01-01 00:00:00.000   2011-01-07 00:00:00.000         1

【讨论】:

  • 你到底是怎么做到的?哇 !我正在检查更多情况......似乎有效。 10 分钟。
  • ;with 子句是否在每次被调用时都运行,或者使用 CTE 可以提高性能...?
  • @RoyiNamir:不,实际上你在这里不需要它。只是使用它,因为我认为您需要进一步汇总结果。
  • 除了unsed的用法,每次调用都会运行Cte?
  • @RoyiNamir:这个 cte 就像一个临时表。我用它来简化。不要将它与递归 CTE 混合。它只是内部查询的容器。
【解决方案2】:

此查询将显示包含大多数事件的单个日期。 CTE tableOfDates 生成从 min(startDate) 到 max(enddate) 的日期表。查询的主要部分只是计算包含这一天的时间间隔。如果您想查看完整列表,请注释掉 top 1 with ties 部分。 There is Sql Fiddle version of it.

; with tableOfDates as (
   select min (startdate) aDate, max(enddate) enddate
     from tbl
   union all
    select aDate + 1, enddate
      from tableOfDates
     where enddate > aDate
)
select top 1 with ties tableOfDates.aDate, count (*)
from tableOfDates
   inner join tbl
      on tableOfDates.aDate >= tbl.startDate
     and tableOfDates.aDate <= tbl.enddate
group by tableOfDates.aDate
order by 2 desc
option (maxrecursion 0)

【讨论】:

    【解决方案3】:

    好问题。

    我会这样做

    • 将所有日期范围扩展到单个/垂直记录。
      将“20110101”、“20110107”变成
      '20110101'
      '20110102'
      '20110103'
      '20110104'
      '20110105'
      '20110106'
      '20110107'

    • 然后,按各个日期分组并返回具有最大计数的日期

    【讨论】:

      猜你喜欢
      • 2022-12-18
      • 2014-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      • 1970-01-01
      • 2021-06-27
      • 1970-01-01
      相关资源
      最近更新 更多