Найти количество дней, которые пересекают данный диапазон дат в таблице диапазонов дат - PullRequest
0 голосов
/ 23 сентября 2019

Я хочу найти общее количество дней в диапазоне дат, которые перекрывают таблицу диапазонов дат.

Например, у меня есть 7 дней между двумя датами в таблице ниже.Я хочу найти дни между ними, которые также попадают в этот диапазон дат: с 2019-08-01 по 2019-08-30.

Возвращается 1 день.

Это запрос источника данных:

SELECT LeaveId, UserId, StartDate, EndDate, Days
FROM TblLeaveRequest
WHERE UserId = 218
LeaveID     UserID      StartDate               EndDate                 Days
----------- ----------- ----------------------- ----------------------- -----------
22484       218         2019-07-26 00:00:00.000 2019-08-01 00:00:00.000 7

Ответы [ 3 ]

2 голосов
/ 26 сентября 2019

Полагаю, это может вам помочь:

--create the table
SELECT 
    22484 LeaveID, 
    218 UserID, 
    CONVERT(DATETIME,'7/26/2019') StartDate, 
    CONVERT(DATETIME,'8/1/2019') EndDate, 
    7 Days
INTO #TblLeaveRequest

--Range Paramters
DECLARE @StartRange AS DATETIME = '8/1/2019'
DECLARE @EndRange AS DATETIME = '8/30/2019'

--Find sum of days between StartDate and EndDate that intersect the range paramters
--for UserId=218
SELECT 
    SUM(
    DATEDIFF(
        DAY
        ,CASE WHEN @StartRange < StartDate THEN StartDate ELSE @StartRange END
        ,DATEADD(DAY, 1, CASE WHEN @EndRange > EndDate THEN EndDate ELSE @EndRange END)
        )
    ) TotalDays
from #TblLeaveRequest
where UserId=218

Предполагается, что никакие даты начала не превышают даты окончания.Также предполагается, что параметры диапазона всегда пересекают некоторую часть диапазона в таблице.

Если диапазоны параметров могут не пересекаться, вам придется исключить эти случаи, исключив отрицательные дни:

SELECT SUM( CASE WHEN Days < 0 THEN 0 ELSE Days END ) TotalDays
FROM
(
SELECT 
    DATEDIFF(
        DAY
        ,CASE WHEN @StartRange < StartDate THEN StartDate ELSE @StartRange END
        ,DATEADD(DAY, 1, CASE WHEN @EndRange > EndDate THEN EndDate ELSE @EndRange END)
        ) Days
from #TblLeaveRequest
where UserId=218
) TotalDays
0 голосов
/ 30 сентября 2019

Вы можете использовать таблицу чисел (Tally) для подсчета количества дней:

SQL Fiddle

Настройка схемы MS SQL Server 2017 :

CREATE TABLE LeaveRequest
(
  LeaveId Int,
  UserId Int,
  StartDate Date,
  EndDate Date,
  Days Int
)

Insert Into LeaveRequest
VALUES
(22484, 218, '2019-07-26','2019-08-01', 7)

Запрос 1 :

DECLARE @StartDate Date = '2019-08-01'
DECLARE @EndDate Date = '2019-08-30'
;WITH Tally
AS
(
  SELECT ROW_NUMBER() OVER (ORdER By Numbers.Num) AS Num
  FROM
  (
    Values(1),(2),(3),(4),(5),(6),(7),(8),(9)
  )Numbers(Num)
  Cross APPLY
  (
    Values(1),(2),(3),(4),(5),(6),(7),(8),(9)
  )Numbers2(Num2)
)
SELECT COUNT(DATEADD(d, Num -1, StartDate)) As NumberOfDays
FROM LeaveRequest
CROSS APPLY Tally
WHERE  DATEADD(d, Num -1, StartDate) <= EndDate AND
DATEADD(d, Num -1, StartDate) >= @StartDate AND
DATEADD(d, Num -1, StartDate) <= @EndDate

Результаты :

| NumberOfDays |
|--------------|
|            1 |
0 голосов
/ 27 сентября 2019

если я правильно понимаю вашу проблему, у вас есть два диапазона дат, и вы ищете количество дней в пересечении.

С учетом диаграммы Ганта:

Start_1 .................... End_1
                 Start_2 .......................End_2

ЕслиВы можете создать структуру таблицы как

LeaveID     UserID      StartDate_1  EndDate_1  StartDate_2  EndDate_2 
----------- ----------- ----------   ---------  ----------   ---------
22484       218         2019-07-26  2019-08-01  2019-08-01   2019-08-30 

Вы можете определить количество дней по

select 
 leaveID
 , UserID
 ,case 
      when StartDate_2 <= EndDate_1 then datediff(day,StartDate_2,EndDate_1) + 1
      else 0
      end as delta_days_intersection
from table

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...