First and Last record including night

Asked

Viewed 94 times

2

I have the following problem I have the data that way:

codigo  data_hora        nome_ajudante
-------+----------------+--------------
1000004 2018-08-22 11:11 Carlos Eduardo
1000004 2018-08-22 11:43 Carlos Eduardo
1000004 2018-08-22 11:48 Carlos Eduardo
1000004 2018-08-22 11:54 Carlos Eduardo
1000004 2018-08-22 17:52 Carlos Eduardo
1000004 2018-08-23 08:13 Carlos Eduardo
1000004 2018-08-23 08:28 Carlos Eduardo
1000004 2018-08-23 10:25 Carlos Eduardo
1000004 2018-08-23 10:25 Carlos Eduardo
1000004 2018-08-23 10:25 Carlos Eduardo
1000004 2018-08-23 13:30 Carlos Eduardo
1000004 2018-08-24 22:20 Carlos Eduardo
1000004 2018-08-24 23:27 Carlos Eduardo
1000004 2018-08-25 03:14 Carlos Eduardo
1000004 2018-08-25 05:12 Carlos Eduardo

I would need to take the first and last time of the day, but also when break is night, so:

codigo  inicio              fim                 nome_ajudante 
-------+-------------------+-------------------+--------------   
1000004 2018-08-22 11:11:00 2018-08-22 17:52:00 Carlos Eduardo
1000004 2018-08-23 08:13:00 2018-08-23 13:30:00 Carlos Eduardo
1000004 2018-08-24 22:20:00 2018-08-25 05:12:00 Carlos Eduardo

I used this query, but days 24 and 25 divided, due to the grouping (GROUP BY).

SELECT 
    MAX(codigo) as codigo
    , MIN(data_hora) AS inicio
    , MAX(data_hora) AS fim
    , nome_ajudante 
FROM
    diarias_ajudantes.registro_terceiros 
GROUP BY nome_ajudante, EXTRACT(DAY FROM data_hora), EXTRACT(MONTH FROM data_hora), EXTRACT(YEAR FROM data_hora)
ORDER BY nome_ajudante, inicio ASC

Does anyone know a way to achieve the expected result?

1 answer

3

At first, your query is correct, it took the smallest and largest data_hora every day.

But if that "night" you say would consider certain times as the previous day, what you can do is, before grouping, remove x hours. For example, if any time before 8:00 is considered the previous day, it would be enough to do so (the problem would be if someone entered earlier in the day, as 07:50 right?):

SELECT 
    codigo as codigo
    , MIN(data_hora) AS inicio
    , MAX(data_hora) AS fim
    , MIN(data_hora - interval '8' hour ) AS inicioConsiderado
    , MAX(data_hora - interval '8' hour) AS fimConsiderado
    , nome_ajudante 
FROM
    test 
GROUP BY codigo, nome_ajudante, EXTRACT(DAY FROM data_hora - interval '8' hour), EXTRACT(MONTH FROM data_hora - interval '8' hour), EXTRACT(YEAR FROM data_hora - interval '8' hour)
ORDER BY nome_ajudante, inicio ASC

SQL Fiddle with my test: http://sqlfiddle.com/#! 17/d77e4/5

PS: Your example data is twice a month up there

Update 01/09/2018 - using an entry schedule table

As @thiagofred asked in the comments, if you have a table indicating the entry times for each employee, the query can use it to calculate each employee’s first entry.

I set the fiddle, which stayed here: http://sqlfiddle.com/#! 17/ecb1b/1

I created a table with the employee code and a whole indicating the time of entry of each employee’s day. With this, just do the Join in the query and adjust the group clause by a little, so:

SELECT 
    test.codigo as codigo
    , MIN(test.data_hora) AS inicio
    , MAX(test.data_hora) AS fim
    , test.nome_ajudante 
FROM
    test
    join horarios on test.codigo=horarios.codigo
GROUP BY
    test.codigo,
    test.nome_ajudante,
    EXTRACT(DAY FROM test.data_hora - interval '1h' * horarios.hora_entrada),
    EXTRACT(MONTH FROM test.data_hora - interval '1h' * horarios.hora_entrada),
    EXTRACT(YEAR FROM test.data_hora - interval '1h' * horarios.hora_entrada)
ORDER BY nome_ajudante, inicio ASC

In the new SQL Fiddle, you can see that the first employee, who starts at 8:00, has one line less than the other, who starts at the same times at 5:00 am.

  • My comrade, thank you. For the above approach was correct, but for times less than 8:00 did not work, as you mentioned before. For the larger sample I have, I changed the interval '8' hour for 6 hours. But in the universe that I will work, there will be time 5h in the morning approximately that will be the beginning of the journey and 7h in the morning that will be the end of the journey. If I had the day you meant it would be quiet, but I won’t have that information.

  • 1

    Really hard there. You’d need an extra field in the table, like data_hora_saida, or a flag indicating whether it is input or output. Another way out, half-way rs, would be to record some more information in the current fields, such as adding a '*' in the helper name indicating the output, or writing positive code for input and negative for output (1000004 is entrance, -1000004 indicates output from the same code).

  • In fact, we will have a device where the person will make interactions, then would need to calculate the time between the first and the last interaction. But people would not have fixed hours for such interaction. Therefore, I have no flag option for this.

  • 1

    These start and end times, do you have them (or could you have) registered for each employee somewhere in the BD? If you have, you could possibly use to subtract these values from the field data_hora

  • If I have a preset shift for each employee on another schedule, would that be possible? For example, the normal shift of this employee would be 08:00 to 18:00. Delays and HE will not be treated here. Would this data help? I thought something might be possible, but I’m not getting it.

  • 1

    Yes, I did an update on the reply to take into account this other table.

  • Understood, but if there is an incidence 5 minutes before, this data will be like the previous day.

  • 1

    Then in the case, you could add a few minutes in group by as well, but the same would be worth for the departure time. 100% solution I think you won’t have, only if you could include more information even in the tegistro table, or even in another that could complement.

  • Thank you for your time, but for now my situation is complicated. I wish I had more information to speed this up, but the worst thing is that I don’t have rs

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.