如何在MSSQL中设置变量并在语句中进一步使用?
set @DOT =((case when[Day 1] > 12 then ([Day 1] - 12) else 0 end)
+ (case when[Day 2] > 12 then ([Day 2] - 12) else 0 end)
+ (case when[Day 3] > 12 then ([Day 3] - 12) else 0 end)
+ (case when[Day 4] > 12 then ([Day 4] - 12) else 0 end)
+ (case when[Day 5] > 12 then ([Day 5] - 12) else 0 end)
+ (case when[Day 6] > 12 then ([Day 6] - 12) else 0 end)
+ (case when[Day 7] > 12 then ([Day 7] - 12) else 0 end))
case when [Timesheet Total] <= 40 and @DOT = 0 then 0
when [Timesheet Total] <= 40 and @DOT > 0 then @DOT
when [Timesheet Total] > 40 and @DOT = 0 then ([Timesheet Total] -40)
when [Timesheet Total] > 40 and @DOT > 0 and ([Timesheet Total] -40) > @DOT then ([Timesheet Total] -40)
when [Timesheet Total] > 40 and @DOT > 0 and ([Timesheet Total] -40) < @DOT then @DOT
else 0
end
答案 0 :(得分:1)
喜欢这样。
DECLARE @DOT INT
SELECT @DOT = ((case when[Day 1] > 12 then ([Day 1] - 12) else 0 end)
+ (case when[Day 2] > 12 then ([Day 2] - 12) else 0 end)
+ (case when[Day 3] > 12 then ([Day 3] - 12) else 0 end)
+ (case when[Day 4] > 12 then ([Day 4] - 12) else 0 end)
+ (case when[Day 5] > 12 then ([Day 5] - 12) else 0 end)
+ (case when[Day 6] > 12 then ([Day 6] - 12) else 0 end)
+ (case when[Day 7] > 12 then ([Day 7] - 12) else 0 end))
case when [Timesheet Total] <= 40 and @DOT = 0 then 0
when [Timesheet Total] <= 40 and @DOT > 0 then @DOT
when [Timesheet Total] > 40 and @DOT = 0 then ([Timesheet Total] -40)
when [Timesheet Total] > 40 and @DOT > 0 and ([Timesheet Total] -40) > @DOT then ([Timesheet Total] -40)
when [Timesheet Total] > 40 and @DOT > 0 and ([Timesheet Total] -40) < @DOT then @DOT
else 0
end
答案 1 :(得分:1)
如果要在同一语句中重用值,则必须使用子查询
SELECT DOT,
case when [Timesheet Total] <= 40 and DOT = 0 then 0
when [Timesheet Total] <= 40 and DOT > 0 then DOT
when [Timesheet Total] > 40 and DOT = 0 then ([Timesheet Total] -40)
when [Timesheet Total] > 40 and DOT > 0 and ([Timesheet Total] -40) > DOT then ([Timesheet Total] -40)
when [Timesheet Total] > 40 and DOT > 0 and ([Timesheet Total] -40) < DOT then DOT
else 0
end
FROM
(SELECT * , ((case when[Day 1] > 12 then ([Day 1] - 12) else 0 end)
+ (case when[Day 2] > 12 then ([Day 2] - 12) else 0 end)
+ (case when[Day 3] > 12 then ([Day 3] - 12) else 0 end)
+ (case when[Day 4] > 12 then ([Day 4] - 12) else 0 end)
+ (case when[Day 5] > 12 then ([Day 5] - 12) else 0 end)
+ (case when[Day 6] > 12 then ([Day 6] - 12) else 0 end)
+ (case when[Day 7] > 12 then ([Day 7] - 12) else 0 end)) AS DOT
FROM YourOriginalTable) SUB
答案 2 :(得分:1)
这个问题尖叫着寻求更好的解决方案。
我假设第1..7天和时间表总数在同一张表中。
让我们创建一个旧的时尚标量函数。我可以做一个ITVF,但语法很难看。
这是一个示例表,功能&amp; tempdb中的数据。
-- Just playing
use tempdb;
go
-- Drop existing
if object_id('my_logic') > 0
drop function my_logic
go
-- Create new
create function my_logic (@i int)
returns int
as
begin
return(select case when @i > 12 then @i - 12 else 0 end as o)
end
go
-- Drop existing
if object_id('my_data') > 0
drop table my_data
go
-- Create new
create table my_data
(
id int,
day1 int,
day2 int,
day3 int,
day4 int,
day5 int,
day6 int,
day7 int,
timesheet int
);
go
-- Add data
insert into my_data values
(99, 1, 12, 2, 13, 3, 14, 4, 50);
go
让我们使用派生表在一个查询中创建该计算。
-- Use the function in the calculation
select
case
when dat.timesheet <= 40 and dot.val = 0
then 0
when dat.timesheet <= 40 and dot.val > 0
then dot.val
when dat.timesheet > 40 and dot.val = 0
then (dat.timesheet-40)
when dat.timesheet > 40 and dot.val > 0 and (dat.timesheet-40) > dot.val
then(dat.timesheet-40)
when dat.timesheet > 40 and dot.val > 0 and (dat.timesheet-40) < dot.val
then dot.val
else 0
end as calc
from
my_data dat
join
(
select
id,
dbo.my_logic(day1) +
dbo.my_logic(day2) +
dbo.my_logic(day3) +
dbo.my_logic(day4) +
dbo.my_logic(day5) +
dbo.my_logic(day6) +
dbo.my_logic(day7)
from
my_data
) dot(id, val) on dat.id = dot.id;
在此示例中,我们有以下输出。
calc
-----------
10
简而言之,内联表值函数(ITVF)将更快;但是,我们必须交叉应用七个函数调用而不是仅添加它们。语法会有点讨厌。
对于小型表和有限的通话,此功能正常。
答案 3 :(得分:1)
如果我正确地阅读您的业务逻辑,您正在计算加班费:
DOT (daily overtime) = sum of all daily hours worked beyond 12 hours / day
WOT (weekly overtime) = number of weekly hours worked beyond 40 hours / week
EOT (effective overtime) = larger of (DOT, WOT)
这可以大大简化来计算所有员工的结果,而不是费力地迭代它们。
SELECT *
FROM tblHoursWorked t1
CROSS APPLY (
SELECT SUM(CASE WHEN [hr] > 12 THEN [hr] - 12 ELSE 0 END)
FROM (VALUES ([Day 1]),([Day 2]),([Day 3]),([Day 4]),([Day 5]),([Day 6]),([Day 7]) ) d(hr)
) t2(DOT)
CROSS APPLY (
SELECT CASE WHEN [TimeSheet Total] > 40 THEN [TimeSheet Total] - 40 ELSE 0 END
) t3(WOT)
CROSS APPLY (
SELECT MAX(OT) FROM ( VALUES (WOT),(DOT) ) w(OT)
) t4(EOT)