【问题标题】:How to limit the aggregation of dates difference in the case of there were overlaps between them在它们之间存在重叠的情况下如何限制日期差异的聚合
【发布时间】:2026-01-16 13:45:02
【问题描述】:

如果日期差异有重叠,如何限制它们的聚合。

如果我有一张这样的任务

   emp_num   from_date                 to_date
   1336       2017-02-07 00:00:00.000   2017-02-08 00:00:00.000
   1336       2017-02-15 00:00:00.000   2017-02-16 00:00:00.000
   1336       2017-02-21 00:00:00.000   2017-02-23 00:00:00.000
   1336       2017-02-26 00:00:00.000   2017-02-26 00:00:00.000
   1336       2017-02-28 00:00:00.000   2017-03-01 00:00:00.000

我想获得一年中特定月份 (to_date - from_date) 的总和。

在这个例子中2-2017年总任务天数的结果应该等于9天


我进行了以下查询,但由于与下个月重叠,我得到 10 days 而不是 9 days!

SELECT b.emp_num,b.NAME AS FullName ,c.DEPTNAME AS DeptName,d.camp_name AS CampName
,SUM(DATEDIFF(day,a.from_date ,a.to_date)+1) AS Mission_SUM
FROM Mission a INNER JOIN Employee b
ON a.emp_num = b.emp_num
INNER JOIN DEPARTMENT c
ON b.dep_code = c.dep_code
INNER JOIN Branch d
ON d.camp_code = b.camp_code
where ((Year(from_date) =2017 AND Month(from_date)=2) OR (Year(to_date) =2017 AND Month(to_date)=2))
and mission_type = 1
GROUP BY b.emp_num,b.NAME,c.DEPTNAME,d.camp_name
ORDER BY d.camp_name,c.DEPTNAME,b.NAME

我想获取员工在 2-2017 的总天数?

【问题讨论】:

    标签: sql sql-server date sql-server-2012 aggregate


    【解决方案1】:

    你可以使用这个查询

    DECLARE @FirstDate date = '2017-02-01'
    DECLARE @EndDate date = EoMonth(@FirstDate)
    
    SELECT b.emp_num,b.NAME AS FullName ,c.DEPTNAME AS DeptName,d.camp_name AS CampName
    ,SUM(DATEDIFF(day,
                IIF(a.from_date > @FirstDate, a.from_date, @FirstDate) ,
                IIF(a.to_date < @EndDate, a.to_date, @EndDate))+1) AS Mission_SUM
    FROM Mission a INNER JOIN Employee b
    ON a.emp_num = b.emp_num
    INNER JOIN DEPARTMENT c
    ON b.dep_code = c.dep_code
    INNER JOIN Branch d
    ON d.camp_code = b.camp_code
    where ((Year(from_date) =2017 AND Month(from_date)=2) OR (Year(to_date) =2017 AND Month(to_date)=2))
    and mission_type = 1
    GROUP BY b.emp_num,b.NAME,c.DEPTNAME,d.camp_name
    ORDER BY d.camp_name,c.DEPTNAME,b.NAME
    

    【讨论】:

      【解决方案2】:

      我是我没有站在你好,但我认为你需要得到迄今为止之间的差异,所以我有创建一个函数来计算这个在年月日它会返回一个表格,所以你可以选择你想要什么价值

      您可以更新它以获得您想要的结果,或者您可以向我寻求帮助以使您获得正确的结果:

      CREATE FUNCTION [dbo].[GetDateDifferenceInYearsMonthsDays]
      (
          @FromDate DATETIME, @ToDate DATETIME
      )
      RETURNS
       @DateDifference TABLE (
       YEAR INT,  MONTH INT, DAYS INT)
      AS
      BEGIN
          DECLARE @Years INT, @Months INT, @Days INT, @tmpFromDate DATETIME = @FromDate
          SET @Years = DATEDIFF(yy, @tmpFromDate, @ToDate) - CASE WHEN (MONTH(@FromDate) > MONTH(@ToDate)) OR (MONTH(@FromDate) = MONTH(@ToDate) AND DAY(@FromDate) > DAY(@ToDate)) THEN 1 ELSE 0 END
      
          SET @tmpFromDate = DATEADD(YEAR, @Years , @FromDate)
          SET @Months =  DATEDIFF(m, @tmpFromDate, @ToDate) - CASE WHEN DAY(@FromDate) > DAY(@ToDate) THEN 1 ELSE 0 END
      
          SET @tmpFromDate = DATEADD(MONTH, @Months , @tmpFromDate)
          SET @Days =  DATEDIFF(d, @tmpFromDate, @ToDate)
      
      
          INSERT INTO @DateDifference
          VALUES(@Years, @Months, @Days)
      
          RETURN
      END
      

      【讨论】:

        【解决方案3】:

        实现此目的的更简单方法如下所示。希望它涵盖所有场景。只考虑了日期。

        CREATE TABLE #TMP (FROMDATE DATE, ENDDATE DATE)
        INSERT INTO #TMP VALUES('2017-02-07','2017-02-08')
        INSERT INTO #TMP VALUES('2017-02-15','2017-02-16')
        INSERT INTO #TMP VALUES('2017-02-21','2017-02-23')
        INSERT INTO #TMP VALUES('2017-02-26','2017-02-26')
        INSERT INTO #TMP VALUES('2017-02-28','2017-03-01')
        
        SELECT SUM(TOTALDAYS) TOTALDAYS
        FROM (
                SELECT TOTALDAYS= 
                        CASE WHEN MONTH(FROMDATE)=MONTH(ENDDATE) AND YEAR(FROMDATE)=YEAR(ENDDATE) THEN SUM(DATEDIFF(D,FROMDATE,ENDDATE))+COUNT(1) 
                            WHEN  MONTH(FROMDATE)!=MONTH(ENDDATE) THEN SUM(DATEDIFF(D,FROMDATE,EOMONTH(FROMDATE)))+1
                        END
                FROM #TMP
                GROUP BY FROMDATE,ENDDATE 
            ) A
        
        DROP TABLE #TMP
        

        【讨论】:

          最近更新 更多