0

我在 MySQL 中有一个表,如下所示:

+----+--------+------------------+------+  
| id | userid | fecha_ingreso    | tipo |  
+----+--------+------------------+------+  
|  1 | 1      | 2015-06-08 20:00 | 1    |  
|  3 | 1      | 2015-06-09 05:00 | 2    |  
| 18 | 2      | 2015-06-09 23:30 | 1    |  
| 19 | 2      | 2015-06-10 05:00 | 2    |  
| 20 | 2      | 2015-06-10 06:00 | 1    |  
| 21 | 2      | 2015-06-10 09:00 | 2    |  
| 22 | 1      | 2015-06-09 23:30 | 1    |  
| 23 | 1      | 2015-06-10 05:00 | 2    |  
| 24 | 1      | 2015-06-10 06:00 | 1    |  
| 25 | 1      | 2015-06-10 09:00 | 2    |  
+----+--------+------------------+------+  
10 rows in set  

这个表有每个用户的信息(userid)谁进入工作和离开工作(fecha_ingreso)。例如,userid=1在 输入 ( tipo=1)'2015-06-08 20:00'并在 离开工作'2015-06-09 05:00'

然后我userid=2有谁tipo=1'2015-06-09 23:30'(夜间)进入()工作,他离开(tipo=2)工作吃早餐,'2015-06-10 05:00'他再次进入,'2015-06-10 06:00'最后他离开了工作'2015-06-10 09:00'

我无法进行仅向我显示如下内容的查询:

+--------+------+---------------------+---------------------+-----------------+ 
| userid | INS | OUTS | time_after_22pm_and_lessOrEqual6am | 
+--------+------+---------------------+---------------------+-----------------+ 
| 1 | 2015-06-25 15:00:00 | 2015-06-26 23:15:00| 01:15:00 
| 2 | 2015-06-25 23:00:00 | 2015-06-26 13:30:00| 07:00:00 
+--------+------+---------------------+---------------------+-----------------+ 
2 rows in set 

这是我需要的输出。即使用户可以有几个进出,我也需要显示他的第一次进入日期时间和最后一次退出日期时间,并在附加列中说明他在第二天 22:00 和早上 6 点的范围内工作了多少小时、分钟和秒.

蒂姆,你的查询很完美,但几乎接近了。但是,当用户在下午 22 点之后(如我的示例所示)时,我不知道如何获取小时:分钟:秒。

4

1 回答 1

0

计算总工作时间应该更容易,假设工人可以在晚上 08:00 之后上班,最多工作 10 小时(您可以调整):

select userid, time_ins, cnt_start, time_outs, cnt_end, seconds,     TIME_FORMAT(SEC_TO_TIME(seconds),'%H:%i:%s') as night_shift
from (
select userid, time_ins, cnt_start, time_outs, cnt_end, 
(select sum(timestampdiff(second, cnt_start,
                case when fecha_ingreso < a.cnt_start then a.cnt_start  
                    when fecha_ingreso > a.cnt_end then a.cnt_end
                    else fecha_ingreso end )  * case when tipo =1 then -1 else 1 end ) seconds 
    from test_t n
    where n.userid = a.userid and n.fecha_ingreso >= a.time_ins and n.fecha_ingreso <=a.time_outs) seconds
from (
 select userid, time_ins, cnt_start, time_outs , 
 case when cast(time_outs as date) = cast(time_ins as date) then time_outs 
    when cast(time_outs as time)>'06:00:00' then       date_add(date(time_outs), interval 6 hour) end cnt_end
 from (
 select userid, time_enter as time_ins , case when cast(time_enter as time) < '20:00:00' then 
    date_add(date(time_enter), interval 22 hour)
     else time_enter end as cnt_start,
     (select max(fecha_ingreso) from test_t l where l.userid=e.userid and l.tipo=2 and l.fecha_ingreso > e.time_enter 
     and l.fecha_ingreso < date_add(e.time_enter, interval 22 hour) )
    as time_outs
  from (
    select userid, min(fecha_ingreso) as time_enter 
      from test_t 
      where cast(fecha_ingreso as time)>='06:00:00'
      and tipo=1
      group by userid ,cast(fecha_ingreso as date)
    ) e
   ) t
  ) a
) ff;

我没有优化它,所以你可以看到步骤。

你可以试试:

select l1.* from l1 
left join (
select l.id, m.id  mid from l1 l 
join l1 m
on l.userid=m.userid and l.tipo=2 and m.tipo=1 and l.fecha_ingreso >=date_add(m.fecha_ingreso, interval -1 hour)
and l.id < m.id) x
on l1.id=x.id or l1.id =x.mid
where mid is null;

它返回

# id, userid, fecha_ingreso, tipo
'1', '1', '2015-06-08 20:00:00', '1'
'3', '1', '2015-06-09 05:00:00', '2'
'18', '2', '2015-06-09 23:30:00', '1'
'21', '2', '2015-06-10 09:00:00', '2'
'22', '1', '2015-06-09 23:30:00', '1'
'25', '1', '2015-06-10 09:00:00', '2'

通过在 1 小时内过滤掉相同用户的任何 1-2 个条目。

于 2015-06-24T03:45:59.807 回答