我有三张表UserInfo
,Departments
& 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在缺席日期缺席。
答案 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)