2011-01-20 46 views
12

Tengo una tabla MySQL donde se registran los tiempos de inicio de sesión y cierre de sesión de los empleados. Aquí en la columna de entrada y salida 1 representa el inicio de sesión y 0 representa el cierre de sesión.Obtenga el total de horas trabajadas en un día mysql

[id] [User_id]   [Date_time]     [in_out] 
    1  1   2011-01-20 09:30:03     1 
    2  1   2011-01-20 11:30:43     0 
    3  1   2011-01-20 11:45:12     1 
    4  1   2011-01-20 12:59:56     0 
    5  1   2011-01-20 13:33:11     1 
    6  1   2011-01-20 15:38:16     0 
    7  1   2011-01-20 15:46:23     1 
    8  1   2011-01-20 17:42:45     0 

¿Es posible recuperar el total de horas trabajadas en un día por un usuario con una sola consulta?

Probé mucho pero todo fue en vano. Puedo hacer esto en PHP utilizando una matriz pero no puedo hacerlo con una sola consulta.

+1

Técnicamente no es posible, pero si usted está buscando el tiempo entre el momento en que se sincronizan en, y cuando se sincronizan fuera, eso es posible! –

+0

@ Alan: sí lo es. – ash

+1

@Jasie: Estaba bromeando sobre el tiempo dedicado al trabajo que no es igual a la diferencia entre el tiempo de entrada y el de salida. –

Respuesta

4
SELECT `User_id`, time(sum(`Date_time`*(1-2*`in_out`))) 
    FROM `whatever_table` GROUP BY `User_id`; 

El (1-2 * `in_out`) término da a cada evento de inicio de sesión de un -1 factores y cada evento de cierre de sesión en un factor 1. La función sum toma la suma de la columna Date_time, y GROUP BY `User_id` hace que se cree la suma para cada usuario diferente.

+0

Cuando 'in_out' es 1, este término es (1-2 * 1) = - 1, lo que hace que el campo' Date_time' para esta fila negativa. Cuando 'in_out' es 0, el término es (1-2 * 0) = 1 y la fila' Date_time' no se altera. Entonces la función 'sum' ve un valor positivo para cada cierre de sesión, y un valor negativo para cada inicio de sesión. Entonces, el resultado de 'sum' es cada evento de cierre de sesión restado por cada evento de inicio de sesión. La función de tiempo alrededor de la suma se utiliza para hacer que la salida sea más clara, ya que el resultado de la suma es un valor de fecha y hora, en algún lugar cerca del año 1 de enero Año 0. – Rudi

+0

esta es una solución realmente creativa. Lo amo. –

+0

No funciona http://sqlfiddle.com/#!9/45870/1/0 –

0

seguirlo:

select [User_id], sum([Time_count])/3600 
from (
    select [User_id], 
     case when [in_out]=1 then UNIX_TIMESTAMP([Date_time]) 
       when [in_out]=0 then - UNIX_TIMESTAMP([Date_time]) 
       end as [Time_count] 
    from my_table 
) as a 
group by [User_id] 

No sé la sintaxis de MySQL por lo que si alguien encuentra errores, por favor corregirlos. Tal vez no pudo funcionar. Por ejemplo, si tiene un usuario conectado. En ese caso, puede filtrar solo a los usuarios que tienen el mismo número de 1 y 0 en el campo [in_out].

4

La línea de pensamiento de Rudi es correcta. Si quiere las horas con decimal, use UNIX_TIMESTAMP() en el campo de fecha y hora; de lo contrario, el tipo devuelto será DATETIME (difícil de analizar). Aquí está el resultado de sus primeros 4 líneas de datos más 2 más para un día diferente:

SELECT 
    `user_id`, 
    DATE(`date_time`) AS `date`, 
    SUM(UNIX_TIMESTAMP(`date_time`)*(1-2*`in_out`))/3600 AS `hours_worked` 
FROM `test` 
GROUP BY date(`date_time`), `user_id`; 
+---------+------------+--------------+ 
| user_id | date  | hours_worked | 
+---------+------------+--------------+ 
|  1 | 2011-01-20 |  3.2567 | 
|  1 | 2011-01-21 |  3.0000 | 
+---------+------------+--------------+ 
+0

Puede reemplazar la "fecha (' fecha_hora') "en GROUP BY con solo" fecha "ya que se definió en la expresión SELECCIONAR ya. – Clutch

Cuestiones relacionadas