用一段 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...