2015-05-31 59 views
-1

我有三個表,分別是UserInfo,Departments & CheckInOut。並按照以下步驟選擇所有錯過日期的日期SQL Server

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和16之間& 17,1月15日日期是日期缺席失蹤。我需要讓James Biser在缺席的日子裏缺席。

+1

你不應該用sp開始你的過程,它是爲了系統過程。 –

+1

除了JamesZ寫的內容之外,還需要使用日曆表的左連接來查看數據中缺少的日期。另外,在這種情況下,不需要動態SQL。使用表值參數將用戶標識傳遞給存儲過程。 –

+0

在哪個日期,該人員不在,不存儲在數據庫中。我需要得到所有日期。 – user2955299

回答

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 
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 
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) 
相關問題