我想计算一个月内一周内的工作天数。我写了这个查询,这可以让我得到日期和日期,但我无法将它们分成几周。
以下是查询:
DECLARE @intEmployeeCode INT = 2309
DECLARE @StartDate datetime;
DECLARE @EndDate datetime;
DECLARE @Month int
DECLARE @Year int
SET @Month = month(getdate())
SET @Year = year(getdate())
SET @StartDate = (select DATEADD(month,month(getdate())-1,DATEADD(year,year(getdate())-1900,0)) ) /*First*/
SET @EndDate = (select DATEADD(day,-1,DATEADD(month,@Month,DATEADD(year,@Year-1900,0))) )/*Last*/
;WITH cte AS (
SELECT
CAST(CAST (@StartDate AS NVARCHAR) AS date) AS myDate
UNION ALL
SELECT DATEADD(day,1,myDate) as myDate
FROM cte
WHERE DATEADD(day,1,myDate) <= CAST(CAST (@EndDate AS NVARCHAR) AS date))
SELECT myDate ,datename(dw,myDate) AS DayOfDate
FROM cte
WHERE datename(dw,myDate) <> 'Sunday'
OPTION (MAXRECURSION 0);
预期结果:
Week Number Working Days
Week 1 5
Week 2 6
Week 3 6
Week 4 6
Week 5 4
答案 0 :(得分:2)
试试这个(代码注释):
DECLARE @intEmployeeCode INT = 2309
DECLARE @StartDate date;
DECLARE @EndDate date;
--I changed your code a little, removed unnecessary variables
--below always returns first and last day of current month
SET @StartDate = DATEADD(dd, -(DATEPART(dd, GETDATE()) - 1), getdate())
SET @EndDate = DATEADD(dd, -1,DATEADD(mm, 1, @StartDate))
;WITH cte AS (
SELECT @StartDate as myDate
UNION ALL
SELECT DATEADD(day,1,myDate) as myDate
FROM cte
WHERE DATEADD(day,1,myDate) <= CAST(CAST (@EndDate AS NVARCHAR) AS date)
)
--in subquery we generate additional column to group by week :)
--we also keep column indicating non-working day, Sunday
select weekGroup + 1 [WeekNumber],
COUNT(*) [WorkingDays]
from (
SELECT myDate,
--here you specify non-working days, now they are sunday - 1 and saturday - 6
case when DATEPART(dw, myDate) in (1,6) then 1 else 0 end isNonWorkingDay,
sum(case DATEPART(dw, myDate) when 1 then 1 else 0 end) over (partition by (select null) order by myDate rows between unbounded preceding and current row) weekGroup
FROM cte
) [a]
where isNonWorkingDay = 0
group by weekGroup
OPTION (MAXRECURSION 0);
答案 1 :(得分:1)
应该可以通过DatePart
来实现,如下所示:
DECLARE @intEmployeeCode INT = 2309
DECLARE @StartDate datetime;
DECLARE @EndDate datetime;
DECLARE @Month int
DECLARE @Year int
SET @Month = month(getdate()) + 2
SET @Year = year(getdate())
SET @StartDate = (select DATEADD(month,month(getdate())-1,DATEADD(year,year(getdate())-1900,0)) ) /*First*/
SET @EndDate = (select DATEADD(day,-1,DATEADD(month,@Month,DATEADD(year,@Year-1900,0))) )/*Last*/
;WITH cte AS (
SELECT
CAST(CAST (@StartDate AS NVARCHAR) AS date) AS myDate
UNION ALL
SELECT DATEADD(day,1,myDate) as myDate
FROM cte
WHERE DATEADD(day,1,myDate) <= CAST(CAST (@EndDate AS NVARCHAR) AS date)
),
cteWeekwise AS(
SELECT myDate ,datename(dw,myDate) AS DayOfDate, DATEPART(YEAR, myDate) cwYear, DATEPART(MONTH, myDate) cwMonth, DATEPART(WEEK, myDate) cw, DENSE_RANK() OVER(PARTITION BY DATEPART(YEAR, myDate), DATEPART(MONTH, myDate) ORDER BY DATEPART(WEEK, myDate)) WeekIdx
FROM cte
WHERE datename(dw,myDate) <> 'Sunday'
)
SELECT WeekIdx, cwYear, cwMonth, cw, COUNT(*) cnt
FROM cteWeekwise
--
WHERE cwYear = 2018
AND cwMonth = 5
AND WeekIdx = 5
--
GROUP BY cwYear, cwMonth, cw, WeekIdx
ORDER BY cwYear, cwMonth, cw
OPTION (MAXRECURSION 0);