iT邦幫忙

4

換算台灣勞工特休新規期間表

恩~來出題玩玩~

根據台灣的特休新規定如下:

(1) 6個月以上1年未滿者,3日。
(2) 1年以上2年未滿者,7日。
(3) 2年以上3年未滿者,10日。
(4) 3年以上5年未滿者,每年14日。
(5) 5年以上10年未滿者,每年15日。
(6) 10年以上者,每1年加給1日,加至30日為止。

參考資料:
https://calc.mol.gov.tw/Trail_New/html/RestDaysNYear.html

若該員工到職日為8/2開始算:

那麼SQL要如何下達,才會像以下圖表(請略過已休天數@@..)
https://ithelp.ithome.com.tw/upload/images/20180802/20061369mWe9cIT26Z.png

按往例~等有人解完,再講我的參考寫法^^a


恩@@a..你們先參考看看吧~

--設定到職日
declare @Job_Date date
set @Job_Date = '2018/8/2'

--設定特休表
declare @Leave table(
	StartMonth int
	,EndMonth int
	,SetDay int
)
declare @i int
set @i = 1

--新增特休規定
while(@i<=26)
begin
	insert into @Leave
	select (
		case when @i = 1
		then 6
		else 12 * (@i - 1)
		end
	)
	,(
		case when @i = 26
		then 0
		else 12 * @i
		end
	)
	,(
		case 
		when @i = 1 then 3
		when @i = 2 then 7
		when @i = 3 then 10
		when @i between 4 and 5 then 14
		when @i between 6 and 10 then 15
		when @i between 11 and 24 then 15 + @i - 10
		else 30
		end
	)
	set @i = @i +1
end

--換算特休期間
select Convert(varchar,dateadd(month,StartMonth,@Job_Date),111) as StartDate
,(
	case when EndMonth = 0
	then N'以上'
	else Convert(varchar,dateadd(day,-1,dateadd(month,EndMonth,@Job_Date)),111)
	end
) as EndDate
,SetDay
from @Leave

線上DEMO展示

神Q超人 iT邦研究生 5 級 ‧ 2018-08-02 15:34:40 檢舉
T-SQL感覺是另一個世界XD
Homura iT邦高手 1 級 ‧ 2018-08-03 16:04:31 檢舉
看到SQL這樣寫都快受不了XD
剛踏入ASP.NET時
看到前人寫的Code
想說程式跑哪去
原來是寫段T-SQL丟到預存程序裡跑...
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
rogeryao
iT邦超人 8 級 ‧ 2018-08-02 17:27:27
最佳解答

這個問題,怪怪的...

SELECT BaseDataB.*,
CASE
WHEN datediff(YEAR, getdate(), TempDateB) - 1 = 0 THEN 3
WHEN datediff(YEAR, getdate(), TempDateB) - 1 = 1 THEN 7
WHEN datediff(YEAR, getdate(), TempDateB) - 1 = 2 THEN 10
WHEN datediff(YEAR, getdate(), TempDateB) - 1 >= 3
AND datediff(YEAR, getdate(), TempDateB) - 1 < 5 THEN 14
WHEN datediff(YEAR, getdate(), TempDateB) - 1 >= 5
AND datediff(YEAR, getdate(), TempDateB) - 1 < 10 THEN 15
WHEN datediff(YEAR, getdate(), TempDateB) - 1 >= 10 THEN
CASE
WHEN ((datediff(YEAR, getdate(), TempDateB) - 1 - 9 ) + 15) > 30 THEN 30
ELSE ((datediff(YEAR, getdate(), TempDateB) - 1 - 9 ) + 15) END
ELSE 0
END AS offday
FROM (SELECT ROW_NUMBER () OVER (ORDER BY number ASC) AS RowNum,
CASE
WHEN ROW_NUMBER () OVER (ORDER BY number ASC) = 1 THEN CONVERT (VARCHAR (8),DATEADD(MONTH, 6, getdate()),112)
WHEN ROW_NUMBER () OVER (ORDER BY number ASC) = 2 THEN CONVERT (VARCHAR (8),DATEADD(MONTH, 12, getdate()),112)
ELSE CONVERT (VARCHAR (8),DATEADD(YEAR,(ROW_NUMBER () OVER (ORDER BY number ASC)) - 1,getdate()),112)
END AS TempDateA,
CASE
WHEN ROW_NUMBER () OVER (ORDER BY number ASC) = 1 THEN CONVERT (VARCHAR (8),DATEADD(DAY ,- 1,DATEADD(MONTH, 12, getdate())),112)
ELSE
CONVERT (VARCHAR (8),DATEADD(DAY ,- 1,DATEADD(YEAR,(ROW_NUMBER () OVER (ORDER BY number ASC)),getdate())),112)
END AS TempDateB
FROM (SELECT TOP 26 number
FROM master..spt_values
) AS BaseDataA
) AS BaseDataB
ORDER BY RowNum

getdate() 可以改成員工到職日
以上程式,部份借用 allenlwh 的程式碼

http://sqlfiddle.com/#!18/9eecb/27696

哈~用master..spt_values的方式~

1
allenlwh
iT邦高手 1 級 ‧ 2018-08-02 10:26:19
//我們是每年12月才計算次年度特休
//onlinedate=到職日(例:2018/8/2)
//yeardate=次年度+到職月日(例:2019/8/2)
case 
    when datediff(YEAR,onlinedate,yeardate)=1 then 7
    when datediff(YEAR,onlinedate,yeardate)=2 then 10
    when datediff(YEAR,onlinedate,yeardate)>=3 and
        datediff(YEAR,onlinedate,yeardate)<5 then 14
    when datediff(YEAR,onlinedate,yeardate)>=5 and
        datediff(YEAR,onlinedate,yeardate)<10 then 15
    when datediff(YEAR,onlinedate,yeardate)>=10 then     
        case 
            when ((datediff(YEAR,onlinedate,yeardate)-9)+15)>30 then 30 
            else ((datediff(YEAR,onlinedate,yeardate)-9)+15) 
        end
    else 0
end as offday
看更多先前的回應...收起先前的回應...

喔??你們是依每年12月統一計算特休壓@@..
我司按照到職日起算~
跟我以前的公司按照每年1/1統一計算有異曲同工之妙
不過這個應該只是計算@@..沒列出整個換算表..(25年吧)

如果依照勞基法,特休假的計算應該是從到職日起算,如果是年底才計算,到頭來可能會使勞工差了幾天的特休假!

我20年前的公司就是以年度計算,我離職時向公司要回差額,公司不肯,我就投訴到勞工局,最後是有拿到一萬元。 (提供參考)

allenlwh iT邦高手 1 級 ‧ 2018-08-02 11:35:01 檢舉

特休的計算還是依勞基法的規定,按到職日計算.
只是統一在12月計算下一個年度的特休天數.
例:到職日2016/1/1.
2018/12/1計算2019年度的特休(2019/1/1~2019/12/31)
例:到職日2016/7/1.
2018/12/1計算2019年度的特休(2019/7/1~2020/6/30)

allenlwh iT邦高手 1 級 ‧ 2018-08-02 11:49:44 檢舉

一次計算25年的特休..如果中間再來"勞基法優化"..就/images/emoticon/emoticon01.gif

呵呵~你們那個是舊制算法~半年沒3天呢Q_Q..
25年呀~我那個是動態顯示的~特休表隨時可以換~
基本上特休還是以員工請假為主@@...
主要秀出~那段期間~
他可以請多少特休~
避免他請超過@@../images/emoticon/emoticon06.gif

allenlwh iT邦高手 1 級 ‧ 2018-08-02 13:06:19 檢舉

滿6個月的部份是每個月檢查未滿一年的員工.
如果滿了6個月,就給3天。
那一段是每個月做檢查,所以就沒列在上面了。

1
evio0502
iT邦新手 2 級 ‧ 2018-08-02 13:50:01

基本上不推薦這樣玩~
應該是開個TABLE~然後排程定期滾算
人員工號、報到日、可休天數、已休天數
然後查詢時SHOW TABLE內容就好了

看更多先前的回應...收起先前的回應...

開排程@@?
我是用一個Table設定25年的期間~
然後帶入到職日,就直接秀出(25年的期間)來了~

如果又有新規~我再換新表就可以了~

evio0502 iT邦新手 2 級 ‧ 2018-08-02 17:14:20 檢舉

如果沒有卡控到請假~這樣是OK
可是如果你特休天數是要卡控請假~
系統判斷特休是否足夠
已休特休~未修特休....
純粹的SELECT VIEW可能不夠用!

在實際系統上~我那個表是實際建檔~
是會判斷可申請特休~當然申請的特休~
超過可休天數~是送不出去的~@@(基本上這又另外一個功能了)

不過~我是有說開題目來玩玩而已~不用理會已休的資料~
純粹顯示特休表讓人查詢而已@@a
讓他知道什麼時候可以請特休唷~
畢竟有人會問他到底什麼時候可以開始請~
然後可以請幾天@@..

allenlwh iT邦高手 1 級 ‧ 2018-08-02 22:44:50 檢舉

實際上我也是開個Table,再排程定期滾算.
把特休天數/已休天數/剩餘天數/可使用的起訖日期分開列出,如果員工要查詢也非常清楚.
https://ithelp.ithome.com.tw/upload/images/20180802/20033493xFqlnmqkSl.jpg

哈~大家都是差不多顯示~

我要發表回答

立即登入回答