SQL 服务器在 Select 语句中分配条件变量

SQL Server Assign Conditional Variable in Select Statement

我不是 SQL 专家,需要一些帮助来解决这个问题。我正在用 SQL Server 2012 数据库编写工资单应用程序,需要跟踪用户打卡、打卡的时间,然后根据工作时间计算工作时间和其他计算。工作时间计算为 9:30 a.m 之间的时间。和 5:30 p.m。逻辑如下:

这是我试过的部分 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.

中遇到困难

你快到了! 以下是您修改后的 SQL 代码。有关 CASE stmt 的完整语法,请参阅 https://docs.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-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
    , 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 的引用,这是不允许的。 "A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations"(实际的 T-SQL 错误信息)。因此,发布的解决方案将显示由五列(Weekday、PunchIn、PunchOut、Start、Stop)组成的结果集。如果您要使用变量并且查询返回了多个记录,那么只有最后一条记录会保存在这些变量中!要将整个集合存储到另一个 table,请添加额外的行

into [table name]

在 "FROM" 关键字之前。

CASE 语句用于选择特定的 值表达式 。该语句必须有一个特定的值结果。 CASE 语句是 not 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 时间是非常违法的。如果员工在他们应该的时间之前打卡上班,这可能是一个纪律问题(管理层会要求他们不要提前上班,开始记录他们,最终解雇他们,等等),但直到这个过程赶上法律规定你必须支付他们工作的时间。同样,这是管辖权,所以请咨询律师,但这确实看起来像是在偷工人的时间。