在SQL Server中的两个日期之间,每年每年每个星期的天数明智的

时间:2018-07-25 12:44:49

标签: sql sql-server sql-server-2008 sql-server-2008-r2

我需要获取两个日期之间的日期和天数值。

假设我们要获取7月1日至8月5日之间的记录。

输出应类似于下表图像:

我们已经知道我们在该日期范围内有 7月月5周和8月 1周 1周:

从第一周到上周开始: enter image description here

3 个答案:

答案 0 :(得分:0)

尝试一下Goutam Singh。我认为现在应该将星期一作为一周的开始,将daycount设为7、2。

SELECT 
    [DYear],    
    [DMonth],   
    [Week], 
    DayCount=COUNT(DISTINCT DayCount),
    BillableHour=SUM(BillableHour)
FROM
(

    SELECT
        [DYear]=(YEAR(Workdate)) ,
        [DMonth]=(DATENAME(MONTH, Workdate)) , 
        DateNames=datename(dw, Workdate),
        [Week]='Week ' + CAST((DATEPART(wk,DATEADD(DAY, -1,Workdate)) - MAX(DATEPART(wk,DATEADD(DAY, -1,Workdate)) )over(partition by (select null))+2) AS varchar(20)), 
        DayCount= (  WorkDate),
        BillableHour=(Convert(DECIMAL(16,2),[Hours]))
    FROM
        @TempTable

    WHERE
        Workdate between CONVERT(datetime,@FromDate) and CONVERT(datetime,@ToDate)
)G
GROUP BY
    [DYear],    
    [DMonth],   
    [Week]

答案 1 :(得分:0)

我不清楚一周中的天数。否则,下面将是查询。只需将值和日期列替换为适当的列名即可。 选择count(value),month(date),datepart(WEEKDAY,date())作为星期数,日期 从T 按日期分组

答案 2 :(得分:0)

@Goutam Singh,我这里有更新版本。基本上,您需要CTE为查询构建模板表,然后根据要获取TotalHours的表中的内容进行联接。让我知道这是否是您想要的。

DECLARE @StartDate DATE='20180101'
DECLARE @EndDate DATE='20180901'

DECLARE @Dates TABLE(
      Workdate DATE  Primary Key
)

 DECLARE @TempTable TABLE (Id INT, Hours real, WorkDate DATETIME )
 INSERT INTO @TempTable
 SELECT 1,   5,   '03.05.2018 00:00:00'  UNION ALL 
 SELECT 2,   1.5,   '08.05.2018 00:00:00'  UNION ALL 
 SELECT 3,   3,   '01.05.2018 00:00:00'  UNION ALL 
 SELECT 4,   0,   '04.05.2018 00:00:00'  UNION ALL 
 SELECT 5,   2,   '03.05.2018 00:00:00'  UNION ALL 
 SELECT 6,   4,   '03.05.2018 00:00:00'  UNION ALL 
 SELECT 7,   2,   '05.05.2018 00:00:00'  UNION ALL 
 SELECT 8,   0.5,   '08.05.2018 00:00:00'  UNION ALL 
 SELECT 9,   0,   '01.05.2018 00:00:00'  UNION ALL 
 SELECT 10,   6,   '08.05.2018 00:00:00'  UNION ALL 
 SELECT 11,   8,   '02.05.2018 00:00:00'  UNION ALL 
 SELECT 12,   3.5,   '09.05.2018 00:00:00'  UNION ALL 
 SELECT 13,   1,   '09.05.2018 00:00:00'  UNION ALL 
 SELECT 14,   4,   '04.05.2018 00:00:00'  UNION ALL 
 SELECT 15,   1,   '03.05.2018 00:00:00'  UNION ALL 
 SELECT 16,   0,   '02.05.2018 00:00:00'  UNION ALL 
 SELECT 17,   3,   '05.05.2018 00:00:00'  UNION ALL 
 SELECT 18,   0.5,   '04.05.2018 00:00:00'  UNION ALL 
 SELECT 19,   2,   '09.05.2018 00:00:00'  UNION ALL 
 SELECT 20,   0,   '09.05.2018 00:00:00' 


 --DATEADD(DAY, -1,Workdate)
;WITH Dates AS(
      SELECT Workdate=@StartDate,WorkMonth=DATENAME(MONTH,@StartDate),WorkYear=YEAR(@StartDate), WorkWeek=datename(wk, DateAdd(DAY,-1,@StartDate)   )
      UNION ALL
      SELECT CurrDate=DateAdd(DAY,1,Workdate),WorkMonth=DATENAME(MONTH,DateAdd(DAY,1,Workdate)),YEAR(DateAdd(DAY,1,Workdate)),datename(wk, Workdate) FROM Dates D WHERE Workdate<@EndDate ---AND (DATENAME(MONTH,D.Workdate))=(DATENAME(MONTH,D.Workdate))
)


SELECT 
    WorkMonth,  
    NumWeek=ROW_NUMBER()OVER(PARTITION BY WorkMonth+cast(WorkYear as varchar(20)) ORDER BY WorkdateStart),
    NumDayWeek,
    WorkYear,   
    WorkdateStart, 
    WorkdateEnd,  
    TotalHours=SUM(TotalHours)
FROM
(


SELECT 
    D.Workdate, 
    D.WorkMonth,    
    D.WorkYear,
    D.WorkWeek, 
    WorkdateStart=MIN(D.Workdate) over(partition by cast(WorkWeek as varchar(20))+workmonth+cast(WorkYear as varchar(20))),
    WorkdateEnd=MAX(D.Workdate) over(partition by cast(WorkWeek as varchar(20))+workmonth+cast(WorkYear as varchar(20))),
    NumDayWeek=datediff(day,MIN(D.Workdate) over(partition by cast(D.WorkWeek as varchar(20))+workmonth+cast(WorkYear as varchar(20))),MAX(D.Workdate) over(partition by cast(D.WorkWeek as varchar(20))+workmonth+cast(WorkYear as varchar(20))))+1,
    T.TotalHours,
    T.DayCount
FROM
    Dates D
    LEFT JOIN
        (
         SELECT T.WorkDate, TotalHours=sum(T.Hours), DayCount=sum(case when T.Hours>0 then 1 else 0 end) FROM 
         @TempTable T
         GROUP BY
         T.WorkDate
        )T ON
         T.WorkDate = D.Workdate    

)Sub



GROUP BY

    WorkMonth,  
    WorkYear,
    WorkdateStart, 
    NumDayWeek,
    WorkdateEnd
ORDER BY
WorkdateStart  

option (maxrecursion 0)