Sql 计算一个时间在一个日期范围内发生的次数

Sql 计算一个时间在一个日期范围内发生的次数,sql,sql-server,sql-server-2008,datetime,Sql,Sql Server,Sql Server 2008,Datetime,如果这个问题已经被问到了,我想不出一个恰当的方式来表达这个问题 我正在寻找一种在SQL2008R2中计算两个datetime值之间发生6pm的次数的方法 例如,“2017-04-17 19:00:00”和“2017-04-19 17:00:00”之间的下午6点仅发生一次,即使时间跨度为3天 在“2017-04-17 18:00:00”和“2017-04-19 18:00:00”之间发生3次,同时也跨越3天 这是一个非常愚蠢的虚构的表达,我想作为例证 timecount(hh, 6, min(da

如果这个问题已经被问到了,我想不出一个恰当的方式来表达这个问题

我正在寻找一种在SQL2008R2中计算两个datetime值之间发生6pm的次数的方法

例如,“2017-04-17 19:00:00”和“2017-04-19 17:00:00”之间的下午6点仅发生一次,即使时间跨度为3天

在“2017-04-17 18:00:00”和“2017-04-19 18:00:00”之间发生3次,同时也跨越3天

这是一个非常愚蠢的虚构的表达,我想作为例证

timecount(hh, 6, min(datefield), max(datefield))

谢谢

这将为您提供每小时和发生次数:

select datepart(hh, DateColumn) as TheHours, count(*) as occurs
from MyTable
where DateColumn between @SomeDate and @SomeOtherDate
group by datepart(hh, DateColumn)
或者只在下午6点:

select count(*)
from MyTable
where datepart(hh, DateColumn) = 18
and DateColumn between @SomeDate and @SomeOtherDate

尝试下面的公式,我已经尝试了不同的方案,它的工作,让我知道,如果我错过了任何方案,并没有按照您的要求工作

DECLARE @firstDate Datetime='17-Apr-2017 17:00:00'
DECLARE @secondDate Datetime='17-Apr-2017 18:59:00'


SELECT
    CASE WHEN DATEDIFF(day,@firstDate,@secondDate)=0
    THEN IIF(CAST(@firstDate AS TIME) <='18:00' AND DATEPART(hh,@secondDate) >=18,1,0)
    ELSE 
        CASE WHEN 
            (
                CAST(@firstDate AS TIME) <='18:00' AND CAST(@secondDate AS TIME) <'18:00' 
                OR
                CAST(@firstDate AS TIME) >'18:00' AND CAST(@secondDate AS TIME) >='18:00' 
            )
            THEN DATEDIFF(day,@firstDate,@secondDate)
            WHEN CAST(@firstDate AS TIME) <='18:00' AND CAST(@secondDate AS TIME) >='18:00' THEN DATEDIFF(day,@firstDate,@secondDate)+1 
            ELSE DATEDIFF(day,@firstDate,@secondDate)-1
            END
    END AS TotalCount

使用CTE尝试下面的脚本


要计数的简单查询:

DECLARE @StartDate datetime = '2017-04-17 18:00:00'

DECLARE @EndDate datetime = '2017-04-19 18:00:00'

SELECT 
   CASE 
      WHEN CAST(@StartDate AS time) <= '18:00' AND CAST(@EndDate AS time) >= '18:00' 
             THEN datediff(day, @StartDate, @EndDate) + 1
      WHEN CAST(@StartDate AS time) <= '18:00' AND CAST(@EndDate AS time) < '18:00' 
             THEN datediff(day, @StartDate, @EndDate)      
      WHEN CAST(@StartDate AS time) > '18:00' AND CAST(@EndDate AS time) >= '18:00' 
             THEN datediff(day, @StartDate, @EndDate)
      ELSE datediff(day, @StartDate, @EndDate) - 1
   END AS TotalCount
以下是两个datetime之间每6点的计数:

以下是两个日期时间之间下午6点的详细视图:


这里给出了任意日期范围之间的计数

declare @time datetime='06:00:00'

declare @startDate datetime='04/20/2017 05:00:00'

declare @enddate datetime='04/21/2017 05:00:00'

SELECT 
  case 
    WHEN datediff(ss,@time, convert(time(0),@startDate)) <=0  and   datediff(ss,@time, convert(time(0),@enddate)) >=0

     THEN datediff(dd,@startDate,@enddate) +1 
WHEN   (datediff(ss,@time, convert(time(0),@startDate)) <=0  and 
datediff(ss,@time, convert(time(0),@enddate)) <=0

        OR
        datediff(ss,@time, convert(time(0),@startDate))> 0  and 

datediff(ss,@time, convert(time(0),@enddate)) >0

        OR

        datediff(ss,@time, convert(time(0),@startDate))> 0  and datediff(ss,@time, convert(time(0),@enddate)) <=0
        )
then  datediff(dd,@startDate,@enddate) 
ELSE  
datediff(dd,@startDate,@enddate)-1
END

如果您有一个很长的日期范围,比如月份或年份,那么如何呢?CTE有一些流:maxrecursion深度和性能。在没有其他方法之前最好避免使用CTE。您好,我在这方面有语法错误,但我不太清楚它是什么,Msg 102,15级,状态1,第7行“不可能,使用我的SQL,我只是重新测试一切可能的:,可能是不同的SQL版本,我不知道...-这可能是个问题,无论您以何种方式得到答案,我认为这不是服务器问题,因为您显示的错误与VersionTanks无关,这很好地完成了工作。
DECLARE @StartDate datetime = '2017-04-17 18:00:00'

DECLARE @EndDate datetime = '2017-04-19 18:00:00'

SELECT 
   CASE 
      WHEN CAST(@StartDate AS time) <= '18:00' AND CAST(@EndDate AS time) >= '18:00' 
             THEN datediff(day, @StartDate, @EndDate) + 1
      WHEN CAST(@StartDate AS time) <= '18:00' AND CAST(@EndDate AS time) < '18:00' 
             THEN datediff(day, @StartDate, @EndDate)      
      WHEN CAST(@StartDate AS time) > '18:00' AND CAST(@EndDate AS time) >= '18:00' 
             THEN datediff(day, @StartDate, @EndDate)
      ELSE datediff(day, @StartDate, @EndDate) - 1
   END AS TotalCount
DECLARE @StartDate datetime
DECLARE @EndDate datetime
set @StartDate = '2017-04-17 19:00:00'
set @EndDate = '2017-04-19 17:00:00'

;WITH cte1 (S) AS (
SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (S)
),
cte2 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte1 AS cte2),
cte3 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte2 AS cte2)

select count(datepart(hour,result)) as count from
(SELECT TOP (DATEDIFF(hour, @StartDate, @EndDate) + 1)
        result = DATEADD(hour, ROW_NUMBER() OVER(ORDER BY S) - 1, @StartDate)
FROM cte3) as res where datepart(hour,result) = 18
DECLARE @StartDate datetime
DECLARE @EndDate datetime
set @StartDate = '2017-04-17 19:00:00'
set @EndDate = '2017-04-19 17:00:00'

;WITH cte1 (S) AS (
SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (S)
),
cte2 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte1 AS cte2),
cte3 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte2 AS cte2)

select result,datepart(hour,result)  from
(SELECT TOP (DATEDIFF(hour, @StartDate, @EndDate) + 1)
        result = DATEADD(hour, ROW_NUMBER() OVER(ORDER BY S) - 1, @StartDate)
FROM cte3) as res where datepart(hour,result) = 18
declare @time datetime='06:00:00'

declare @startDate datetime='04/20/2017 05:00:00'

declare @enddate datetime='04/21/2017 05:00:00'

SELECT 
  case 
    WHEN datediff(ss,@time, convert(time(0),@startDate)) <=0  and   datediff(ss,@time, convert(time(0),@enddate)) >=0

     THEN datediff(dd,@startDate,@enddate) +1 
WHEN   (datediff(ss,@time, convert(time(0),@startDate)) <=0  and 
datediff(ss,@time, convert(time(0),@enddate)) <=0

        OR
        datediff(ss,@time, convert(time(0),@startDate))> 0  and 

datediff(ss,@time, convert(time(0),@enddate)) >0

        OR

        datediff(ss,@time, convert(time(0),@startDate))> 0  and datediff(ss,@time, convert(time(0),@enddate)) <=0
        )
then  datediff(dd,@startDate,@enddate) 
ELSE  
datediff(dd,@startDate,@enddate)-1
END