选择SQL Server缺少日期的所有日期

时间:2015-05-31 09:12:35

标签: sql-server date stored-procedures

我有三张表UserInfoDepartments& CheckInOut。并通过以下程序

ALTER procedure [dbo].[spGetLogs] 
@DateFrom datetime, 
@DateTo datetime, 
@UserID varchar(max) 

as  
begin 
declare @Query varchar(max) 
set @Query =  'SELECT Badgenumber, Name, min(checktime) as [Check Time],    CHECKTYPE as [Check Type] 
    from USERINFO  
        inner join DEPARTMENTS as dept
            on USERINFO.DEFAULTDEPTID = dept.DEPTID 
        inner join CHECKINOUT
            on USERINFO.USERID = CHECKINOUT.USERID 
    where CHECKINOUT.USERID in (' + @UserID + ')  and CHECKTIME between ''' + CONVERT(varchar, ( @DateFrom )) + ''' AND ''' + CONVERT(varchar, ( @DateTo  )) +  ''' 
    group by CHECKINOUT.userid, USERINFO.Badgenumber, USERINFO.Name, CHECKTYPE, CONVERT(varchar, checktime, 101) order by CHECKINOUT.userid'

    print @Query 
    Exec (@Query) 
  end  

exec spGetLogs'01/14/2015', '03/31/2015', 1

结果如下

1001    James Biser 2015-01-14 06:42:47.000 I 
1001    James Biser 2015-01-17 06:38:06.000 I 
1001    James Biser 2015-01-18 06:42:58.000 I 
1001    James Biser 2015-01-19 06:38:00.000 I 
1001    James Biser 2015-01-20 06:43:45.000 I 
1001    James Biser 2015-01-21 06:42:14.000 I 
1001    James Biser 2015-01-22 06:41:43.000 I 
1001    James Biser 2015-01-24 07:25:31.000 I 
1001    James Biser 2015-01-25 06:39:14.000 I 
1001    James Biser 2015-01-26 06:35:48.000 I 
1001    James Biser 2015-01-27 06:39:07.000 I 
1001    James Biser 2015-01-28 06:49:51.000 I 
1001    James Biser 2015-01-29 06:47:28.000 I 
1001    James Biser 2015-01-31 07:21:18.000 I 
1001    James Biser 2015-02-01 06:33:34.000 I 

我需要证明员工在这里失踪的日期缺席,如14和14之间。 1月17日,15日和16日缺少日期。我需要证明James Biser在缺席日期缺席。

3 个答案:

答案 0 :(得分:0)

如果日期包含您需要的每一天的行(例如,1.1.2000 - 31.12.2099),您应该创建一个表。有了这个,你可以这样做:

SELECT 
  U.Badgenumber, 
  U.Name, 
  D.[Date],
  C.Checktime,
  C.Checktype
from 
  USERINFO U
  join DEPARTMENTS as D
    on U.DEFAULTDEPTID = D.DEPTID
  cross join Dates D
  outer apply (
    select top 1 CHECKTIME, CHECKTYPE
    from CHECKINOUT C 
    where 
      U.USERID = C.USERID and 
      C.CHECKTIME >= D.[Date] and 
      C.CHECKTIME < dateadd(day, 1, D.[Date])
    order by
      C.CHECKTIME asc
  ) C
where 
  U.USERID in (' + @UserID + ')  and 
  D.[Date] >= ''' + CONVERT(varchar, @DateFrom, 112 ) + ''' AND
  D.[Date] < ''' + CONVERT(varchar, dateadd(day, 1, @DateTo), 112) +  ''' 
group by 
  U.USERID, 
  U.Badgenumber, 
  U.Name
order by 
  U.USERID

答案 1 :(得分:0)

尝试使用这样的解决方案:

;WITH t AS (
     SELECT CAST('2015-03-01' AS datetime) AS d
UNION ALL SELECT '2015-03-02'
UNION ALL SELECT '2015-03-03'
UNION ALL SELECT '2015-03-04'
UNION ALL SELECT '2015-03-07'
UNION ALL SELECT '2015-03-08'
UNION ALL SELECT '2015-03-09'
UNION ALL SELECT '2015-03-10'
UNION ALL SELECT '2015-02-27'
UNION ALL SELECT '2015-02-28'
UNION ALL SELECT '2015-03-20'
UNION ALL SELECT '2015-03-19'
UNION ALL SELECT '2015-03-17'
UNION ALL SELECT '2015-03-16'
), t1 AS (
    SELECT DISTINCT 
        MIN(t.d) OVER (PARTITION BY NULL) minD, 
        MAX(t.d) OVER (PARTITION BY NULL) maxD
    FROM 
        t
)
, CTE(d, i) AS (
    SELECT TOP(1) t1.minD, 1
    FROM t1
    UNION ALL
    SELECT DATEADD(DAY, 1, CTE.d), CTE.i + 1
    FROM CTE 
        JOIN
        t1  ON CTE.d < t1.maxD
)
SELECT CTE.d
FROM 
    CTE
    LEFT JOIN
    t ON CTE.d = t.d
WHERE
    t.d IS NULL
ORDER BY i

结果如下:

d
2015-03-05 00:00:00.000
2015-03-06 00:00:00.000
2015-03-11 00:00:00.000
2015-03-12 00:00:00.000
2015-03-13 00:00:00.000
2015-03-14 00:00:00.000
2015-03-15 00:00:00.000
2015-03-18 00:00:00.000

答案 2 :(得分:0)

如果您可以将存储过程的结果集放入表(我称之为GetLogs)或临时表中,或者将下面的代码与您的存储过程(CTE,函数等)结合起来,那么您可以提供日期人缺席。

DECLARE @CHECKTIME datetime
SET @CHECKTIME = (SELECT MIN([Check Time]) FROM GETLOGS)
SELECT @CHECKTIME AS [CHECKTIME] INTO CT1
WHILE @CHECKTIME < (SELECT MAX([CHECK TIME])+1 FROM GetLogs)
BEGIN
INSERT INTO CT1 SELECT @CHECKTIME
SET @CHECKTIME = (@CHECKTIME + 1) 
END
SELECT CONVERT(VARCHAR,CHECKTIME,101) FROM CT1 WHERE CONVERT
(VARCHAR,CHECKTIME,101) NOT IN (SELECT CONVERT(VARCHAR,[Check Time],101)
FROM GETLOGS)