我当前的表格是:
USERID Department NAME actualdate
522 xyz department John Wayne 2/17/14 8:34
522 xyz department John Wayne 2/17/1411:21
789 xyz department Bill Smith 2/17/14 9:41
789 xyz department Bill Smith 2/17/14 11:16
789 xyz department Bill Smith 2/17/14 11:50
789 xyz department Bill Smith 2/17/14 12:18
856 xyz department Raul Castil 2/17/14 9:25
我想创建一个允许我输入用户ID并从该用户返回数据的函数。但是,我想取第一行并获取实际日期,然后将其存储在列'check in'中,并将最后一行存储在列调用中'检出'。
基本上每天我都要记录用户的入住时间并查看每天的时间。
这就是我到目前为止所做的“
CREATE FUNCTION [dbo].[GetEmployeeTime]
(
@useridd int
)
RETURNS @RtnValue TABLE
(
useridd int,
deptname varchar(max),
emplname varchar(100),
actualDate datetime,
checkIn datetime,--first row of the actual date goes here
checkOut datetime -- last row of the actual date goes here
)
AS
BEGIN
DECLARE @userid int,@checkin datetime, @checkout datetime;
DECLARE @useridAndDate varchar(max), @useridAndDate2 varchar(max);
DECLARE Curs CURSOR FOR
select ch.USERID AS useridd,ch.CHECKTIME as actualdate
from CHECKINOUT ch
left join USERINFO ui on ui.USERID=ch.USERID
left join DEPARTMENTS dep on dep.DEPTID=ui.DEFAULTDEPTID
OPEN Curs;
FETCH NEXT FROM Curs INTO @useridd, @actualdate;
WHILE @@FETCH_STATUS=0
---so confuse here to loop through rows to record only first and last row.
set @useridAndDate= @useridd + @actualdate
--if @useridAndDate != @useridAndDate2
--begin
--end
FETCH NEXT FROM Curs INTO @useridd,@actualdate
close Curs;
deallocate Curs;
Return;
END
我希望最终结果如下:
USERID Department NAME actualdate checkin checkout
522 xyz department John Wayne 2/17/14 8:34 2/17/14 8:34 2/17/14 11:21
789 xyz department Bill Smith 2/17/14 9:41 2/17/14 9:41 2/17/14 12:18
856 xyz department Raul Castil 2/17/14 9:25 2/17/14 9:25
答案 0 :(得分:1)
这不需要Cursor。你只需要分区 每个用户的最大值和最小值,只需区分它们
SELECT DISTINCT USERID,Department,NAME,FIR checkTime,
CASE WHEN FIR=SEC THEN NULL ELSE SEC END checkOut
FROM
(
SELECT *,
MIN(CAST(CHECKTIME AS TIME)) OVER (PARTITION BY(USERID))FIR,
MAX(CAST(CHECKTIME AS TIME)) OVER (PARTITION BY(USERID))SEC
FROM TimePunch
)TAB
答案 1 :(得分:0)
你可以用GROUP BY做到这一点。
游标有很大的开销,虽然对程序控制很有用,但它们通常不适合回答基于集合的查询。
具有DATEADD(DAY, 0, DATEDIFF(DAY, 0, actualdate))
的部分只会将该值截断到当天的开头,因此我可以在不同日期获取签到和结帐。我假设它是某种类型的DATETIME数据类型,并且舍入它使用的方法几乎适用于所有版本的SQL Server(因为你没有指定你正在使用的那个)。
SELECT
USERID,
Department,
NAME,
DATEADD(DAY, 0, DATEDIFF(DAY, 0, actualdate)) AS date,
MIN(CHECKTIME) AS checkIn,
MAX(CHECKTIME) AS checkOut
FROM
CHECKINOUT
GROUP BY
1, 2, 3, 4
注意:如果任何日期字段是字符串,则可能存在问题。然后,我强烈建议改变事物,使它们成为DATETIME / TIME / DATE字段。