【问题标题】:How to Construct a Single Row from a Multi Row Subset in SQlLSERVER如何在 SQLSERVER 中从多行子集构造单行
【发布时间】:2017-03-08 07:04:37
【问题描述】:

我有一种情况,员工有 time-in 和 time-out 但他们被保存到一个类型为 [in =1 ,out = 2] 的列中,我需要获取单个员工的时间(进出)在一行中,用 Time-In、Time-Out 标题分隔。

这是我的表格示例,

CREATE TABLE #Employee
(
empid int,
name varchar(20),
age int
)
CREATE TABLE #TIMEINOUT
(
    id int,
    empid int,
    timeinout datetime,
    [type] tinyint
)

INSERT INTO #Employee values(1,'Benny',35)
INSERT INTO #Employee values(2,'Algo',32)


INSERT INTO #TIMEINOUT VALUES(1,1,'2017-03-08 06:00:00 AM',1) -- (Type 1 = IN , 2 = Out)
INSERT INTO #TIMEINOUT VALUES(2,1,'2017-03-08 05:00:00 PM',2) -- (Type 1 = IN , 2 = Out)
INSERT INTO #TIMEINOUT VALUES(3,2,'2017-03-08 07:00:00 AM',1) -- (Type 1 = IN , 2 = Out)
INSERT INTO #TIMEINOUT VALUES(4,2,'2017-03-08 09:00:00 PM',2) -- (Type 1 = IN , 2 = Out)



SELECT * FROM #Employee INNER JOIN #TIMEINOUT ON #Employee.empid = #TIMEINOUT.empid

Select #Employee.empid,#Employee.name,#Employee.age,GETDATE() as TimeIN,GETDATE() as TimeOUT from #Employee

DROP TABLE #Employee
DROP TABLE #TIMEINOUT

谁能帮忙简化查询?

【问题讨论】:

  • 预期输出应该是
  • @Chanukya..我已经编辑并选择了预期结果
  • 您需要按 empid 和按日期执行此操作吗?
  • 类型是什么意思? 1是IN,2是OUT?
  • @reds 无论如何,我需要员工在单行输出中出勤,子表中有两行

标签: sql sql-server time-and-attendance


【解决方案1】:

也许是这样的? TimeinTimeOut 的单独列

;with cte as (
SELECT e.empid,e.name,e.age,t.timeinout as TimeIn FROM #Employee e INNER  JOIN #TIMEINOUT t ON e.empid = t.empid
 where t.type=1
 )
 select t.empid,t.name,t.age,t.timein as TimeIn,t2.timeinout as Timeout from cte t

 inner join (
select * from #timeinout
where type=2
)t2
 on t.empid=t2.empid

【讨论】:

  • 他只是错过了 t2.empid
  • 这是否适用于同一用户的多次进出?
  • 这取决于type 列是否具有12 值。
  • @DareDevil 再试一次 我只是错过了t2.empid
  • @JackyMontevirgen 它的工作原理,但不能简单,所以可以在 Oracle 中使用它吗?
【解决方案2】:

看看这个:

select a.empid,a.timeinout,b.timeinout from 
(select *,CONVERT(VARCHAR(10),timeinout,110) as this_in from TIMEINOUT where type = 1) as a
inner join
(select *,CONVERT(VARCHAR(10),timeinout,110) as this_out from TIMEINOUT where type = 2) as b
on a.empid = b.empid where a.this_in = b.this_out

【讨论】:

  • 如果您想要员工姓名,只需加入员工即可。
  • 很好的方法,我只是想全选然后选择一个具有相同 emp_id 和相同日期但不同日期的 LEFT 连接列作为超时类型
  • 日期很重要,这就是为什么我将其包含在 where 子句中以确保
  • 你的数据结构的问题是如果超时日期超过一天怎么办?你可以删除我猜的 where 子句,如果每个员工只有 2 条记录,这很有效。一进一出。
【解决方案3】:

我就是这样做的,

SELECT  #Employee.empid ,
    #Employee.name ,
    #TIMEINOUT.timeinout [TimeIN],
    X.timeinout [TimeOUT]
FROM    #Employee
    INNER JOIN #TIMEINOUT ON #TIMEINOUT.empid = #Employee.empid
    LEFT JOIN ( SELECT  #TIMEINOUT.empid ,
                        #TIMEINOUT.timeinout
                FROM    #TIMEINOUT
                WHERE   type = 2
              ) X ON X.empid = #Employee.empid
                     AND CONVERT(VARCHAR(10), #TIMEINOUT.timeinout, 111)   = CONVERT(VARCHAR(10), X.timeinout, 111)
WHERE   #TIMEINOUT.type = 1

【讨论】:

    猜你喜欢
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 2015-07-06
    • 1970-01-01
    • 2017-04-17
    • 2020-09-16
    • 1970-01-01
    相关资源
    最近更新 更多