我不是SQL专家,需要一些帮助来解决这个问题。我正在编写一个带有SQL Server 2012数据库的工资单应用程序,需要跟踪用户打孔,打孔,然后根据工作时间计算工作时间和其他计算的时间。工作时间计算为上午9:30至下午5:30之间的时间。这是逻辑:
这里是我试过的部分SQL,但没有到达任何地方。任何帮助将不胜感激:
declare @start time;
declare @end time;
select @start=cast('09:30:00.0000000' as time)
select @end=cast('17:30:00.0000000' as time)
SELECT Datename(dw,LastUpdate) as WeekDay
,FORMAT(PunchIn,'MM/dd/yyyy hh:mm tt') as PunchIn
,FORMAT(PunchOut,'MM/dd/yyyy hh:mm tt') as PunchOut
,case
--employee punched in before 9:30 so take 9:30 as start time
when datediff(mi,@start,cast(PunchIn as time))<0 then (select @start='09:30:00.0000000') end
from TimeTracker
这不是完整的SQL,但您可以看到我尝试使用的逻辑。我的问题是如何根据另一列中的值设置开始时间或结束时间,例如打卡时间或打卡时间。 SQL在select语句中给出了一个错误,作为when子句的一部分。我可以在其他语言中轻松完成这项任务,但在SQL中难以接受。
答案 0 :(得分:0)
你快到了! 下面是您修改过的SQL代码。有关CASE stmt。
的完整语法,请参阅https://docs.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sqldeclare @start time;
declare @end time;
select @start=cast('09:30:00.0000000' as time)
select @end=cast('17:30:00.0000000' as time)
SELECT Datename(dw,LastUpdate) as WeekDay
, FORMAT(PunchIn,'MM/dd/yyyy hh:mm tt') as PunchIn
, FORMAT(PunchOut,'MM/dd/yyyy hh:mm tt') as PunchOut
, Start = case
--employee punched in before 9:30 so take 9:30 as start time
when datediff(mi,@start,cast(PunchIn as time)) < 0 then @start
else cast(PunchIn as time)
end
, Stop = case
--employee punched out after 17:30 so take 17:30 as end time
when datediff(mi,@end,cast(PunchOut as time)) > 0 then @end
else cast(PunchOut as time)
end
from TimeTracker
注意:您的原始代码包含对变量@start的引用,这是不允许的。 “为变量赋值的SELECT语句不能与数据检索操作相结合”(实际的T-SQL错误消息)。因此,发布的解决方案将显示包含五列(Weekday,PunchIn,PunchOut,Start,Stop)的结果集。如果您要使用变量并且从查询返回多个记录,那么只有最后一条记录将保存在这些变量中!要将整个集存储到另一个表中,请添加其他行
into [table name]
在“FROM”关键字之前。
答案 1 :(得分:0)
CASE
语句用于选择特定的值表达式。声明必须有特定的值结果。 CASE
语句不 if
条件...它们不会评估为可执行代码。
所以不要这样:
--Bad
CASE WHEN 1=0 THEN Select @x=4+@y ELSE Select @x=2+@y END
你必须做这样的事情:
--Better
SELECT @x = CASE WHEN 1=0 THEN 4+@y ELSE 2+@y END
这表明您仍然可以在表达式中添加一些代码,但它仍然必须评估为值。
对于这里的问题,它看起来应该更像这样:
case
--employee punched in before 9:30 so take 9:30 as start time
when datediff(mi,@start,cast(PunchIn as time))<0 then '09:30:00.0000000'
else PunchIn end
虽然我仍然怀疑在这里做作业。
此代码也很有趣,因为在我所见过的大多数司法管辖区,改变像这样的PunchIn时代是非常不合法的。如果一名员工在他们被认为可能是一个纪律问题之前就会上班(管理层会要求他们不要提前进入,开始写他们,最终解雇他们等等),但是直到这个过程赶上法律说你必须支付他们工作的时间。同样,这是司法管辖权,所以请咨询律师,但这确实看起来像是在偷工人的时间。