使用SQL Server 2000:
SELECT PERSONID,
CARDEVENTDATE,
INTIME,
CASE
WHEN OUTTIME = INTIME THEN
'No PunchOut'
ELSE
OUTTIME
END AS OUTTIME,
CONVERT(char(8), CASE
WHEN DateAdd(Day, - DateDiff(Day, 0, OutTime), OutTime) > '18:00:00' THEN
Cast('18:00:00' AS datetime)
ELSE
DateAdd(Day, - DateDiff(Day, 0, OutTime), OutTime)
END - CASE
WHEN DateAdd(Day, - DateDiff(Day, 0, InTime), InTime) < '09:00:00' THEN
Cast('09:00:00' AS datetime)
ELSE
DateAdd(Day, - DateDiff(Day, 0, InTime), InTime)
END, 8) AS WorkTime
FROM (SELECT T_PERSON.PERSONID,
T_CARDEVENT.CARDEVENTDATE,
MIN(T_CARDEVENT.CARDEVENTTIME) AS INTIME,
MAX(T_CARDEVENT.CARDEVENTTIME) AS OUTTIME
FROM T_PERSON
INNER JOIN T_CARDEVENT ON T_PERSON.PERSONID = T_CARDEVENT.PERSONID
GROUP BY T_PERSON.PERSONID, T_CARDEVENT.CARDEVENTDATE) DERIVEDTBL
T_cardevent.cardeventtime列数据类型为Varchar。
表中Cardeventtime值为080002,091235 ....所以......,
执行上述查询时,显示Arithmetic Express Overflow错误,将表达式转换为数据类型Datetime。
答案 0 :(得分:2)
所以这个“080002”代表什么? 8小时0分2秒?
这绝对不是开箱即用的有效DATETIME格式 - 它也不符合任何有效的SQL Server CONVERT styles。
因此,您必须自己手动进行一些转换。你有没有机会用这个列将表包装到一个可以处理转换的视图中?
你必须做一些事情:
CONVERT(DATETIME, SUBSTRING(CardEventTime, 1, 2) + ':' +
SUBSTRING(CardEventTime, 3, 2) + ':' +
SUBSTRING(CardEventTime, 5, 2), 8)
这应该将您的“080002”转换为“08:00:02”,然后可以使用样式号将其转换为DATETIME(直到SQL Server 2008没有单独的时间数据类型)。 8(hh:mm:ss)。
马克
答案 1 :(得分:0)
我在这里做了一系列的假设,但没有能够测试它,但这是一个可能的解决方案:
SELECT PERSONID,
CARDEVENTDATE,
INTIME,
CASE
WHEN OUTTIME = INTIME THEN
'No PunchOut'
ELSE
OUTTIME
END AS OUTTIME,
Stuff(Stuff(Right('000000' +
CONVERT(varchar(5), CASE
WHEN Convert(int,OutTime) > 180000 THEN
180000
ELSE
Convert(int,OutTime)
END - CASE
WHEN Convert(int,InTime) < 90000 THEN
90000
ELSE
Convert(int,InTime)
END), 6),5,0,':'),3,0,':')
AS WorkTime
FROM (SELECT T_PERSON.PERSONID,
T_CARDEVENT.CARDEVENTDATE,
MIN(T_CARDEVENT.CARDEVENTTIME) AS INTIME,
MAX(T_CARDEVENT.CARDEVENTTIME) AS OUTTIME
FROM T_PERSON
INNER JOIN T_CARDEVENT ON T_PERSON.PERSONID = T_CARDEVENT.PERSONID
GROUP BY T_PERSON.PERSONID, T_CARDEVENT.CARDEVENTDATE) DERIVEDTBL
我没有频繁使用Stuff,因此插入点可能已关闭。