SQL 求解每月週末天數

2022-08-26 10:24:08 字數 4229 閱讀 3445

用一段 sql 查詢某月的週末(包含週六,週日)的天數。

用到的方法:

1 多種日期函式

2 tally table 校驗

原理:

1 求得每月有多少天數

2 計算第乙個完整的自然周需要補齊多少天, 並計算本週的實際週末天數

3 將剩下的天數(月總天數- 補掉的天數)除以 7 , 餘數為 0 則取商數 * 2 作為週末天數, 餘數不為0, 則去商數 * 2 + 1 作為週末天數

------  **實現部分  ---------

為了檢驗演算法的正確性,需要統計出 2014 年到 2018 年的每月週末數量,可以用 tally table 計算. tally table 的概念,在這篇文章中說得清楚:

/*--------------------------

tally table 生成 2014 年到 2018 年的日期基礎表

統計基礎表每月的假日數目

對比求解每月假日數目的 sql 指令碼

--------------------------/

-- 此處是 1. tally table 生成 2014 年到 2018 年的日期基礎表 和 2. 統計基礎表每月的假日數目

create table fctmonthlyweekends ( curr_year int, curr_month int, monthly_weekend_count int)

declare @begin datetime = dateadd(d,-1,'2014-01-01')

,@end datetime = '2018-12-31'

declare @inc int;

select @inc = datediff(day, @begin, @end);

with l0

as (select * from ( values (1) ,(2) ,(3)) as t(c)),l1 as (select a.c,b.c as bc  from l0 as a  cross join l0 as b),l2 as (select a.c

,b.c as bc  from l1 as a  cross join l1 as b) ,l3 as (select a.c,b.c as bc  from l2 as a cross join l2 as b) ,l4 as (select a.c,b.c as bc

from l3 as a   cross join l3 as b),l5 as (select a.c,b.c as bc from l4 as a   cross join l4 as b)

insert into fctmonthlyweekends(curr_year,curr_month,monthly_weekend_count)

select curr_year, curr_month, sum(dayofweek_flag) as monthly_weekend_count

from ( select top (@inc)   datepart(year,dateadd(day, rnk, @begin) ) as curr_year

,datepart(month,dateadd(day, rnk, @begin) ) as curr_month

, dateadd(day, rnk, @begin) as curr_date,case 

when datepart(dw,dateadd(day, rnk, @begin) ) in(1,7)  then 1 else 0 

end as dayofweek_flag    from ( select row_number() over (order by ( select null)) as rnk   from l5) m  order by rnk) tmp 

group by curr_year,curr_month 

order by curr_year,curr_month

--3. 對比求解每月假日數目的 sql 指令碼,同樣計算 2014 年到 2018 年的每月週末假期數目create table fctmonthlyweekends_t ( curr_year int, curr_month int, monthly_weekend_count int)

declare @curr_day datetime = convert(date,'2014-01-05')

declare @curr_month_begin_day datetime = dateadd(day,-1* day(@curr_day) + 1, @curr_day)

declare @next_month_begin_day datetime = dateadd(month,1,@curr_month_begin_day)

declare @curr_month_day_count int = datediff(day,@curr_month_begin_day,@next_month_begin_day) 

declare @curr_month_rest_day int = 0 

while (year(@curr_day)<2019)

begin 

set @curr_month_rest_day = datepart(dw,@curr_month_begin_day ) - 8 + @curr_month_day_count

insert into fctmonthlyweekends_t(curr_year,curr_month,monthly_weekend_count)

select year(@curr_day) as c_year,month(@curr_day) as c_month,head_count + body_count  

from (select case when datepart(dw, @curr_month_begin_day) = 1 then 2   else 1 

end as head_count, 

case when (@curr_month_rest_day) % 7 = 0 then (@curr_month_rest_day / 7 )*2 

else  floor(@curr_month_rest_day / 7 ) * 2   + 1 

end as body_count) t

select @curr_day = dateadd(month,1,@curr_day)

select @curr_month_begin_day   = dateadd(day,-1* day(@curr_day) + 1, @curr_day)

select @next_month_begin_day   = dateadd(month,1,@curr_month_begin_day)

select @curr_month_day_count   = datediff(day,@curr_month_begin_day,@next_month_begin_day) 

end

-- 對比校驗

select t.*, s.* 

from fctmonthlyweekends_t t

inner join  fctmonthlyweekends s on t.curr_year = s.curr_year and t.curr_month  = s.curr_month

where s.monthly_weekend_count <> t.monthly_weekend_count

計算每月員工住宿的天數

說明 本系統把宿舍管理融合為一體系統處理 宿舍安排,水電費計算,宿舍管理可根據實際情況調配人員,很直觀。最主要的是水電運算 剛開始考察的結果 按每間宿舍每月計算水電,不管是本月離職的,還是剛搬進的,還是月間調到其它宿舍的,都得要考慮計算進去,人工計算的時候,他們一般以10天為乙個運算單位,這就是實際...

輸出每月的天數 華為機試題

輸入含年月的字串,僅支援資訊格式為mm yyyy mm 月份,yyyy 年份 根據該訊息輸出當月總天數。注意考慮閏年。1 公曆年份是4的倍數且不是100的倍數。2 公曆年份是400的倍數 例如,2000年是閏年,1900則是平年。閏年2月份為29天,平年2月份為28天。執行時間限制 無限制 記憶體限...

SQL計算天數

1 計算給定時間段的實際月份天數 select trunc sysdate to date 2013 06 28 yyyy mm dd from dual 2 給定乙個月份計算這個月份的天數 select to char last day to date 2013 07 yyyy mm dd fro...