带有不同表的多种情况

时间:2019-10-31 07:47:03

标签: sql sql-server case

我有这样的查询:

select U.Name,U.Adluserid as 'Empid', 
       min(case when IOType=0 then Edatetime end) as 'IN',
       max(case when IOType=1 then Edatetime end) as 'out'
       from Mx_ACSEventTrn
inner join Mx_UserMst U on Mx_ACSEventTrn.UsrRefcode=U.UserID
left join Tbl_Zeo_Empstatus E on  Mx_ACSEventTrn.UsrRefcode=E.Emp_Id
where cast(Edatetime as date) between '2019-10-30' and '2019-10-30' 
group by U.Name,U.Adluserid

输出

 Name            Empid     IN                          OUT                status           
JAS             505  2019-10-30 08:06:37.000    2019-10-30 14:13:29.000   Present
SAAJ            516  2019-10-30 08:05:11.000    2019-10-30 14:17:58.000   Absent
ram             516  2019-10-30 08:20:11.000    2019-10-30 14:17:58.000   Late

我还有另一个这样的表:Tbl_Zeo_Empstatus

Emp_Id  Status
123      2
504      2
505      3
  • 我想根据此条件显示状态列。如果准时 不为null,则检查时间是否超过8.15 AM。如果超过 然后,上午8.15显示其他明智的表演。

  • 如果时间为null,则从此检查员工的状态 表“ Tbl_Zeo_Empstatus”,如果状态2,则显示“缺席”,如果状态3 然后显示这样的“假期”。

我该如何实现?

2 个答案:

答案 0 :(得分:1)

您需要一个附加的查询级别(子选择),以能够在inout时间(总计和最小值)上运行。为了能够使用Tbl_Zeo_Empstatus连接数据,我们需要使用u.UserID提供外部查询,然后根据该列执行左连接。

最终查询只需要一个CASE表达式即可评估您的条件并根据in时间列设置预期状态。

select
  t.Name,
  t.Empid,
  t.t_in,
  t.t_out,
  case 
    when t.t_in is null and E.status = 2 then 'Absent'
    when t.t_in is null and E.status = 3 then 'Vacation'
    when cast(t.t_in as time) > '08:15' then 'Late' else 'Present' 
    end as status
from (
  select 
    u.UserID,
    u.Name,
    u.Adluserid as empid, 
    min(case when IOType=0 then Edatetime end) as t_in,
    max(case when IOType=1 then Edatetime end) as t_out,
  from 
    Mx_ACSEventTrn t
    inner join Mx_UserMst u on t.UsrRefcode = u.UserID
  where 
    cast(Edatetime as date) between '2019-10-30' and '2019-10-30' 
  group by 
    u.UserId, u.Name, u.Adluserid
) t
left join Tbl_Zeo_Empstatus e on t.UserID = e.Emp_Id

答案 1 :(得分:0)

尝试避免这样的内部选择

select 
    u.UserID,
    u.Name,
    u.Adluserid as empid, 
    min(case when IOType=0 then Edatetime end) as t_in,
    max(case when IOType=1 then Edatetime end) as t_out
    into #tmp 
from 
    Mx_ACSEventTrn t
    inner join Mx_UserMst u on t.UsrRefcode = u.UserID
where 
    cast(Edatetime as date) between '2019-10-30' and '2019-10-30' 
group by 
u.UserId, u.Name, u.Adluserid

select
  t.Name,
  t.Empid,
  t.t_in,
  t.t_out,
  case 
    when t.t_in is null and E.status = 2 then 'Absent'
    when t.t_in is null and E.status = 3 then 'Vacation'
    when cast(t.t_in as time) > '08:15' then 'Late' else 'Present' 
    end as status
from 
#tmp t
left join Tbl_Zeo_Empstatus e on t.UserID = e.Emp_Id