如何在SQL Server中的表的列中获取丢失的日期

时间:2019-02-21 05:49:14

标签: sql-server function

我有一张包含以下记录的表

DateIn      TimeIn
----------------------------
2019-02-01  09:31:00.0000000
2019-02-02  09:35:00.0000000
2019-02-04  09:27:00.0000000
2019-02-05  09:34:00.0000000
2019-02-06  09:32:00.0000000
2019-02-09  09:38:00.0000000
2019-02-11  09:35:00.0000000
2019-02-12  15:09:00.0000000
2019-02-13  09:31:00.0000000
2019-02-14  09:35:00.0000000
2019-02-15  09:35:00.0000000
2019-02-16  09:37:00.0000000
2019-02-18  09:33:00.0000000
2019-02-19  09:31:00.0000000

所以2019-02-03,2019-02-07,2019-02-08,2019-02-10,2019-02-17缺少日期

所以我想要以下格式的结果

DateIn      TimeIn
----------------------------
2019-02-01  09:31:00.0000000
2019-02-02  09:35:00.0000000
2019-02-03  null
2019-02-04  09:27:00.0000000
2019-02-05  09:34:00.0000000
2019-02-06  09:32:00.0000000
2019-02-07  null
2019-02-08  null
2019-02-09  09:38:00.0000000
2019-02-10  null
2019-02-11  09:35:00.0000000
2019-02-12  15:09:00.0000000
2019-02-13  09:31:00.0000000
2019-02-14  09:35:00.0000000
2019-02-15  09:35:00.0000000
2019-02-16  09:37:00.0000000
2019-02-17  null
2019-02-18  09:33:00.0000000
2019-02-19  09:31:00.0000000

为此,我创建了函数“ GetAllDates”,该函数返回给定日期之间的所有日期,并且按以下方式使用了此功能

Select 
    TA.DateIn, TA.TimeIn
from  
    [ES].[getAllDates]('20190201','20190228') DD 
left outer join   
    [ES].[tblAttendance] TA on Cast(TA.DateIn as date) = cast(DD.date as date) 
where 
    TA.PersonId = 21

此查询返回以下结果:

DateIn      TimeIn
----------------------------
2019-02-01  09:31:00.0000000
2019-02-02  09:35:00.0000000
2019-02-04  09:27:00.0000000
2019-02-05  09:34:00.0000000
2019-02-06  09:32:00.0000000
2019-02-09  09:38:00.0000000
2019-02-11  09:35:00.0000000
2019-02-12  15:09:00.0000000
2019-02-13  09:31:00.0000000
2019-02-14  09:35:00.0000000
2019-02-15  09:35:00.0000000
2019-02-16  09:37:00.0000000
2019-02-18  09:33:00.0000000
2019-02-19  09:31:00.0000000

结果不正确。请帮助我找到解决方法

3 个答案:

答案 0 :(得分:2)

一种简单的方法是在日期上将日历表与当前表连接起来,如下所示:

WITH dates AS (
    select date from [ES].getAllDates('20190201','20190228')
)

SELECT
    d.date,
    t.TimeIn
FROM dates d
LEFT JOIN [ES].[tblAttendance] t
    ON d.date = t.DateIn and t.PersonId = 21
ORDER BY
    d.date;

@PSK 可能的答案是有效的,假设您的tblAttendance表实际上已经存在每个日期的数据。如果没有,那么仅将WHERE限制移至ON子句可能仍会在当前日期留下一些漏洞。

答案 1 :(得分:1)

如果要获取WHERE条记录,请用LEFT JOIN移动NULL查询。

SELECT TA.datein, 
       TA.timein 
FROM   [ES].[Getalldates]('20190201', '20190228') DD 
       LEFT OUTER JOIN [ES].[tblattendance] TA 
                    ON Cast(TA.datein AS DATE) = Cast(DD.date AS DATE) 
                       AND TA.personid = 21 

答案 2 :(得分:0)

首先创建日期记录,然后与当前记录左连接。

    GO

        DECLARE  @arrival_date date = '2019-01-01',
             @leaving_date date = '2019-02-01'

    ;WITH DD AS (
    SELECT @arrival_date as date_
    UNION ALL
    SELECT CAST(DATEADD(day,1,date_) as date)
    FROM DD
    WHERE date_ < @leaving_date
    )
    select DD.date_ as DateIn,  TA.TimeIn as TimeIn from DD LEFT OUTER JOIN [ES].[tblattendance] TA 
                ON Cast(TA.datein AS DATE) = Cast(DD.date_ AS DATE) 
                   AND TA.personid = 21 

    GO