自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何用SQL只統(tǒng)計工作日的數(shù)據(jù)?

數(shù)據(jù)庫 MySQL
因為我們工作中其實(shí)很多時候確實(shí)只需要統(tǒng)計大家工作日的數(shù)據(jù),比如考勤,有的甚至還有排除一些法定節(jié)假日(這個問題大家可以思考一下如何解決)。

[[388028]]

本文轉(zhuǎn)載自微信公眾號「SQL數(shù)據(jù)庫開發(fā)」,作者丶平凡世界。轉(zhuǎn)載本文請聯(lián)系SQL數(shù)據(jù)庫開發(fā)公眾號。

今天微信群里有位讀者提了個問題:如何用SQL統(tǒng)計一個月里工作日的數(shù)據(jù)?

我覺得這個問題問的挺好的,因為我們工作中其實(shí)很多時候確實(shí)只需要統(tǒng)計大家工作日的數(shù)據(jù),比如考勤,有的甚至還有排除一些法定節(jié)假日(這個問題大家可以思考一下如何解決)。

下面我們針對讀者提出的這個問題,用SQL來進(jìn)行求解。

題目

求解員工“張三”工作日上了多少天班?

測試數(shù)據(jù)

  1. CREATE TABLE Tmp0317 
  2. 姓名 VARCHAR(20), 
  3. 上班時間 DATETIME, 
  4. 下班時間 DATETIME 
  5.  
  6. INSERT INTO Tmp0317 VALUE ('張三','2021-03-01 08:05:03','2021-03-01 18:25:26'
  7. INSERT INTO Tmp0317 VALUE ('張三','2021-03-03 08:12:12','2021-03-01 18:01:16'
  8. INSERT INTO Tmp0317 VALUE ('張三','2021-03-04 08:11:24','2021-03-01 18:09:25'
  9. INSERT INTO Tmp0317 VALUE ('張三','2021-03-05 08:15:08','2021-03-01 18:14:43'
  10. INSERT INTO Tmp0317 VALUE ('張三','2021-03-09 08:20:26','2021-03-01 18:23:48'
  11. INSERT INTO Tmp0317 VALUE ('張三','2021-03-10 08:23:16','2021-03-01 18:19:04'
  12. INSERT INTO Tmp0317 VALUE ('張三','2021-03-11 08:19:13','2021-03-01 18:26:29'
  13. INSERT INTO Tmp0317 VALUE ('張三','2021-03-12 08:17:42','2021-03-01 18:11:12'
  14. INSERT INTO Tmp0317 VALUE ('張三','2021-03-13 08:15:37','2021-03-01 18:10:05'

分析

要求解工作日的天數(shù),只需要排除掉周末即可,這里我們暫不考慮忘打卡的情況。我們可以借助SQL Server里面的系統(tǒng)表spt_values來進(jìn)行求解

具體解法

  1. SELECT  
  2. SUM
  3. CASE WHEN DATEPART(WEEKDAY,DATEADD(DD,NUMBER,'2021-03-01' )) IN (1,7)  
  4. THEN 0  ELSE 1 END 
  5. AS WORKDAY 
  6. FROM MASTER..SPT_VALUES 
  7. JOIN Tmp0317 ON DATEADD(DAY, NUMBER, CONVERT(DATE'2021-03-01'))=CONVERT(DATE,上班時間) 
  8. WHERE TYPE='P'  
  9. AND NUMBER BETWEEN 0 AND DATEDIFF(DAY'2021-03-01', DATEADD(MONTH, 1, '2021-03-01'))-1 

(提示:可以左右滑動代碼)

結(jié)果為:

我們可以對照日歷表看下,“張三”在這幾天的工作日打開記錄:

其中紅色框表示工作日,綠色框表示周末,張三總共9條記錄,13日周六這天應(yīng)該是回公司加班了,但是我們不算正常工作日的考勤記錄,所以結(jié)果是8.

代碼解析

上面的代碼估計很多讀者看的有點(diǎn)懵,這里我們將代碼先拆解開,看下每個函數(shù)里面的結(jié)果什么,大家就知道了。

首先是spt_values這個系統(tǒng)表,我們在之前的文章里有提到過具體的用法。

其次我們看下關(guān)聯(lián)條件:

  1. JOIN Tmp0317 ON  
  2. DATEADD(DAY, NUMBER, CONVERT(DATE'2021-03-01'))=CONVERT(DATE,上班時間) 

這里我們單獨(dú)看等號兩本的結(jié)果:

  1. SELECT  
  2. DATEADD(DAY, NUMBER, CONVERT(DATE'2021-03-01')) 
  3. FROM MASTER..SPT_VALUES  
  4. WHERE TYPE='P'  
  5. AND NUMBER BETWEEN 0 AND DATEDIFF(DAY'2021-03-01', DATEADD(MONTH, 1, '2021-03-01'))-1 

注意:這里必須加上后面的WHERE條件部分,其中后面的

DATEDIFF(DAY, '2021-03-01', DATEADD(MONTH, 1, '2021-03-01'))-1

的結(jié)果是30,這里因為我們的NUMBER是從0開始,所以后面要減去1,即從0-30,表示3月共31天

查詢出的結(jié)果如下:

后面還有16-31日的記錄未截取,大家可以去自己電腦上試驗一下。

然后再看等號右邊的結(jié)果:

  1. SELECT CONVERT(DATE,上班時間)  
  2. FROM Tmp0317 

結(jié)果如下:

這樣,我們就可以通過關(guān)聯(lián)條件來獲取到我們需要的上班日期了,但是這并不是工作日的上班日期,我們最后還要做一個判斷,那就是SELECT后面的CASE WHEN條件了。

CASE WHEN里面的代碼我們也單獨(dú)執(zhí)行一下:

  1. SELECT  
  2.  
  3. DATEADD(DD,NUMBER,'2021-03-01' ), 
  4. DATEPART(WEEKDAY,DATEADD(DD,NUMBER,'2021-03-01' )) AS WORKDAY 
  5.  
  6. FROM MASTER..SPT_VALUES 
  7. JOIN Tmp0317 ON DATEADD(DAY, NUMBER, CONVERT(DATETIME, '2021-03-01'))=CONVERT(DATE,上班時間) 
  8. WHERE TYPE='P' AND NUMBER BETWEEN 0 AND DATEDIFF(DAY'2021-03-01', DATEADD(MONTH, 1, '2021-03-01'))-1 

我們將DATEPART里面的嵌套函數(shù)DATEADD也單獨(dú)拎出來,看下執(zhí)行結(jié)果:

圖片

這里的DATEPART的功能主要是用來返回這一天是這個星期的第幾天,我們的系統(tǒng)日歷是按照美國的歷法,每周的第一天是星期日,所以2021-03-01的星期一是本周的第二天,以此類推,我們得到每一天對應(yīng)在本周的第幾天。

知道這個結(jié)果后,我們可以得知,每個周的第2-6天是對應(yīng)我們的工作日,那么我們可以取這個結(jié)果IN (2,3,4,5,6) 也可以 NOT IN (1,7)。

這里我們用CASE WHEN取的反義詞,當(dāng)它IN (1,7)時我們返回0,表示不統(tǒng)計,其他結(jié)果返回1,表示統(tǒng)計。

即:

  1. SELECT  
  2.  
  3. DATEADD(DD,NUMBER,'2021-03-01' ), 
  4. DATEPART(WEEKDAY,DATEADD(DD,NUMBER,'2021-03-01' )), 
  5. CASE WHEN DATEPART(WEEKDAY,DATEADD(DD,NUMBER,'2021-03-01' )) IN (1,7) THEN 0  ELSE 1 END AS WORKDAY 
  6.  
  7. FROM MASTER..SPT_VALUES 
  8. JOIN Tmp0317 ON DATEADD(DAY, NUMBER, CONVERT(DATETIME, '2021-03-01'))=CONVERT(DATE,上班時間) 
  9. WHERE TYPE='P' AND NUMBER BETWEEN 0 AND DATEDIFF(DAY'2021-03-01', DATEADD(MONTH, 1, '2021-03-01'))-1 

結(jié)果為:

對WORKDAY列進(jìn)行SUM求和就得到了我們的結(jié)果8

Q:這里能不使用spt_values嗎?

A:可以的,只需要構(gòu)建一張臨時表,表結(jié)構(gòu)也只需要一列,就是一列自增長的連續(xù)整數(shù)即可

 

責(zé)任編輯:武曉燕 來源: SQL數(shù)據(jù)庫開發(fā)
相關(guān)推薦

2012-10-11 15:32:53

筆記本聯(lián)想工作站

2022-04-30 07:53:54

Python腳本語言

2013-04-15 09:52:13

程序員

2015-11-11 16:52:49

高清視頻會議華為

2019-10-15 15:15:31

Python大數(shù)據(jù)函數(shù)

2017-11-16 09:20:00

CIOERP信息化

2014-05-27 10:09:21

大數(shù)據(jù)

2021-08-08 22:08:41

Redis開發(fā)網(wǎng)頁

2012-09-10 10:26:22

工作工作習(xí)慣調(diào)整心態(tài)

2023-08-22 08:01:42

SpringBatch事務(wù)管理

2010-04-01 10:20:30

Oracle時間日期操

2021-04-20 08:33:29

SQL快照數(shù)據(jù)

2019-12-06 13:55:28

人社部大數(shù)據(jù)應(yīng)用場景

2019-04-26 13:20:24

數(shù)據(jù)庫PostgreSQL Oracle

2019-08-01 15:47:25

數(shù)據(jù)備份遷移

2019-11-26 11:19:40

統(tǒng)計數(shù)據(jù)互聯(lián)網(wǎng)

2021-01-12 11:31:09

數(shù)據(jù)科學(xué)數(shù)據(jù)大數(shù)據(jù)

2015-08-14 14:29:00

數(shù)據(jù)分析

2021-02-22 14:40:11

5G5G網(wǎng)絡(luò)5G終端

2010-04-20 14:06:56

Oracle SQL語
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號