Re: Suma de columna en una semana

From: Brunhilde Sibeth <bruma13sibeth(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org, Jaime Casanova <jaime(dot)casanova(at)2ndquadrant(dot)com>
Subject: Re: Suma de columna en una semana
Date: 2018-02-09 17:30:13
Message-ID: CAHC9sYk=OR0EJtNwi-PHiz+4XASvRfeyfc2gQ4rMM0bTJLc5oA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Buenas a todos nuevamente,

Me fue genial la ayuda que me brindaron y quiero abusar con otra
consulta, ya que volví a estancarme en otro punto que creo es más de
lógica, aunque puede que postgres tenga una función que pueda facilitarme
la tarea, o tal vez lo extensa de mi consulta es lo que me tiene mareada.

Con el aporte armé una consulta que actualizará con valores una
tabla. La consulta está de modo prueba, para ir viendo si cumple con lo que
necesito.

Esto es el resultado de la consulta, donde solo me voy a centrar a modo de
ejemplo en una semana (del rango de un mes), obtengo:

Fecha Hs_total Hs_total_2 HORA HORA_CALCULADA
2018-01-15 11:41:00 00:00:00 03:41:00 00:00:00
2018-01-16 12:07:00 00:00:00 04:07:00 00:00:00
2018-01-17 12:09:00 00:00:00 04:09:00 00:00:00
2018-01-18 08:52:00 - 00:52:00 00:52:00
2018-01-19 08:23:00 00:00:00 00:23:00 00:23:00

Necesitaba identificar el numero de semana para hacer una sumatoria de la
columna HORA la cual por semana no debe pasar el total de 08:00:00 hs para
que la la columna HORA _CALCULADA no supere en sumatoria el total de 8 hs
semanal. Obviamente en HORA se mantiene los valores originales para no
perder esa información.

Con la consulta lo que quiero lograr es lo siguiente como por dia puede
alcarzar en HORA_CALCULADA hasta 03:00:00 y en la semana 08:00:00; lo
siguiente es lo que necesito obtenrer;

Fecha Hs_total Hs_total_2 HORA HORA_CALCULADA
2018-01-15 11:41:00 00:00:00 03:41:00 03:00:00
2018-01-16 12:07:00 00:00:00 04:07:00 03:00:00
2018-01-17 12:09:00 00:00:00 04:09:00 02:00:00
2018-01-18 08:52:00 - 00:52:00 00:00:00
2018-01-19 08:23:00 00:00:00 00:23:00 00:00:00

Mi consulta super extensa (inconscientemente siempre voy por el camino más
largo):

SELECT registros.fecha,
registros.hs_total,registros.hs_total_2,registros.HORA,
CASE WHEN registros.hs_total::interval IS NULL AND
(registros.hs_total_2::interval > '08:49:00'::interval) THEN
CASE WHEN
(registros.hs_total_2::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=1 THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha)IN (1)) >='08:00:00' )THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS EXTRAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (1))<='07:59:00') THEN

registros.hs_total_2::interval-'08:00:00'::interval --COLOCA LAS
HORAS

ELSE

registros.hs_total_2::interval-'08:00:00'::interval

END

WHEN ((registros.hs_total_2::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=2 )THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (2))>'08:00:00') THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (2))<='07:59:00') THEN

registros.hs_total_2::interval-'08:00:00'::interval --COLOCA LAS
HORAS

ELSE

registros.hs_total_2::interval-'08:00:00'::interval

END

WHEN (registros.hs_total_2::interval-'08:00:00'::interval)>'03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=3 THEN

CASE WHEN ( SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (3))>='08:00:00' THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS EXTRAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (3))<='07:59:00') THEN

registros.hs_total_2::interval-'08:00:00'::interval --COLOCA LAS
HORAS

ELSE

registros.hs_total_2::interval-'08:00:00'::interval

END

WHEN (registros.hs_total_2::interval > '08:49:00'::interval
AND (registros.hs_total_2::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=4 )THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (4))>='08:00:00') THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (4))<='07:59:00') THEN

registros.hs_total_2::interval-'08:00:00'::interval --COLOCA LAS
HORAS

ELSE

registros.hs_total_2::interval-'08:00:00'::interval

END

WHEN (registros.hs_total_2::interval > '08:49:00'::interval
AND (registros.hs_total_2::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=5 )THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (5))>='08:00:00') THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (5))<='07:59:00') THEN

registros.hs_total_2::interval-'08:00:00'::interval --COLOCA LAS
HORAS

ELSE

registros.hs_total_2::interval-'08:00:00'::interval

END

WHEN ( registros.hs_total_2::interval-'08:00:00'::interval )<
'00:00:00'::interval THEN
'00:00:00'::interval
ELSE
registros.hs_total_2::interval-'08:00:00'::interval
END
ELSE
CASE WHEN ( registros.hs_total::interval > '08:49:00'::interval
AND ( registros.hs_total::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=1 )THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (1))>='08:00:00') THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (1))<='07:59:00') THEN

registros.hs_total::interval-'08:00:00'::interval --COLOCA LAS HORAS

ELSE

registros.hs_total::interval-'08:00:00'::interval

END

WHEN (registros.hs_total::interval > '08:49:00'::interval
AND (registros.hs_total::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=2 )THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (2))>='08:00:00') THEN

(SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (2)) - (SELECT HORA FROM
control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha= registros.fecha)

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (2))<='07:59:00') THEN

registros.hs_total::interval-'08:00:00'::interval --COLOCA LAS HORAS

ELSE

registros.hs_total::interval-'08:00:00'::interval

END

WHEN ((registros.hs_total::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=3 )THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (3)
)>='08:00:00') THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha)IN (3))<='07:59:00') THEN

registros.hs_total::interval-'08:00:00'::interval --COLOCA LAS HORAS

ELSE

registros.hs_total::interval-'08:00:00'::interval

END

WHEN (registros.hs_total::interval > '08:49:00'::interval
AND (registros.hs_total::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=4 )THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (4))>='08:00:00') THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (4))<='07:59:00') THEN

registros.hs_total::interval-'08:00:00'::interval --COLOCA LAS HORAS

ELSE

registros.hs_total::interval-'08:00:00'::interval

END

WHEN (registros.hs_total::interval > '08:49:00'::interval
AND (registros.hs_total::interval-'08:00:00'::interval)>='03:00:00'
AND EXTRACT (WEEK FROM registros.fecha)=5 )THEN

CASE WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (5))>='08:00:00') THEN

'00:00:00'::interval -- NO COLOCA LAS HORAS

WHEN ( (SELECT SUM(HORA)
FROM control_asistencia.presentismo_aux
WHERE personal_id= registros.personal_id
AND fecha NOT IN (registros.fecha)
AND EXTRACT (week from fecha) IN (5))<='07:59:00') THEN

registros.hs_total::interval-'08:00:00'::interval --COLOCA LAS HORAS

ELSE

registros.hs_total::interval-'08:00:00'::interval

END

WHEN (registros.hs_total::interval -'08:00:00') < '00:00:00'::interval
THEN
'00:00:00'::interval
ELSE
(registros.hs_total::interval -'08:00:00')
END
END AS normativas_70
FROM tabla registros
WHERE registros.personal_id=?
AND registros.fecha BETWEEN '2018-01-01' AND '2018-01-31'
AND (registros.dia NOT LIKE ('S%')
OR registros.dia NOT LIKE ('Do%'))
ORDER BY registros.fecha;

Espero les parezca interesante y puedan ayudarme.

Agradecida..

Buenas Jaime!
>
> Bien, te comento el porqué del no tomar en cuenta el domingo, estoy
> controlando días hábiles laborales (*de lunes a sábado*) sinceramente con
> la función DOW como cada día siempre será el mismo valor numérico,pensaba
> restar o realizar alguna operación para recuperar siempre un mismo día como
> el inicio de semana(*a mí elección*).
> Y en esa una semana no debe sobrepasar mi SUM(HORAS) la cantidad de 08:00
> hs totales.
>
> SELECT EXTRACT(week from fecha), SUM(HORAS)
> FROM tabla
> WHERE personal_id= ?
> AND fecha BETWEEN ‘2018-02-01’ AND ‘2018-02-28’
> AND EXTRACT (DOW from fecha) IN (1,2,3,4,5,6)
> GROUP BY 1
> ORDER BY fecha;
>
> Con esta consulta recuperé la semana a la que corresponde cada fecha y
> haré la consulta que corresponde.
>
> Muchísimas gracias por tu ayuda y pronta respuesta.
>
> Saludos.
>
>
> El 8 de febrero de 2018, 14:59, Jaime Casanova <
> jaime(dot)casanova(at)2ndquadrant(dot)com> escribió:
>
>> 2018-02-08 11:40 GMT-05:00 Brunhilde Sibeth <bruma13sibeth(at)gmail(dot)com>:
>> > Buenas a todos!
>> >
>> > Es la primera vez que consulto a la lista, espero puedan ayudarme y
>> reciba
>> > alguna orientación o respuesta.
>> > En la actualidad me estoy familiarizando con el postgresql.
>> >
>> > Lo que necesito es sumar una columna de una tabla (valor en horas) , el
>> > inconveniente que encuentro es que la suma debe ser por semana, dentro
>> del
>> > rango de un mes.
>> >
>> > Tengo algo armado así, pero necesito que el control me haga detectando
>> la
>> > fecha de inicio y fin de la semana
>> > según la fecha en la que está el puntero (hace un recorrido por fila
>> /fecha
>> > dentro de la tabla), esta consulta sería una condición para realizar
>> otra
>> > operación dentro de un CASE, ya que la cantidad de la suma de horas no
>> debe
>> > ser mayor a 8 hs en una semana.
>> >
>> > Espero ansiosa que puedan ayudarme.
>> >
>> > SELECT SUM(HORAS)
>> > FROM tabla
>> > WHERE personal_id= ?
>> > AND fecha BETWEEN ‘2018-02-01’ AND ‘2018-02-28’
>> > AND EXTRACT (DOW from fecha) IN (1,2,3,4,5,6)
>> > ORDER BY fecha
>> >
>>
>> alguna razón por la que pides que ignore el domingo? "EXTRACT (DOW
>> from fecha) IN (1,2,3,4,5,6)"
>>
>> Ahora, para que la suma sea por semana deberías usar algo así aunque
>> se te dará el número de semana del año. Si quieres el número de semana
>> del mes habría que ver tu definición de semana; por ejemplo: si el mes
>> empieza en domingo, esa sería la primera semana? o la siguiente?
>> especialmente considerando que estas ignorando los domingos pero la
>> misma pregunta se puede hacer si el mes empieza en sábado o cuentas de
>> sábado a sábado?
>>
>> SELECT EXTRACT(week from fecha), SUM(HORAS)
>> FROM tabla
>> WHERE personal_id= ?
>> AND fecha BETWEEN ‘2018-02-01’ AND ‘2018-02-28’
>> AND EXTRACT (DOW from fecha) IN (1,2,3,4,5,6)
>> GROUP BY 1
>> ORDER BY fecha;
>>
>> una posible solución si cuentas la semana de domingo a domingo sería:
>>
>> SELECT EXTRACT(week from fecha), SUM(HORAS)
>> FROM tabla
>> WHERE personal_id= ?
>> AND fecha BETWEEN ‘2018-02-01’ AND ‘2018-02-28’
>> GROUP BY EXTRACT(week from fecha)
>> ORDER BY 1;
>>
>> o
>>
>> WITH horas_semana (semana, horas) AS (SELECT EXTRACT(week from fecha),
>> SUM(HORAS)
>> FROM
>> tabla
>> WHERE
>> personal_id= ?
>>
>> AND fecha BETWEEN ‘2018-02-01’ AND ‘2018-02-28’
>> GROUP
>> BY EXTRACT(week from fecha))
>> SELECT row_number() over (), horas
>> FROM horas_semana
>> ORDER BY semana;
>>
>>
>> --
>> Jaime Casanova www.2ndQuadrant.com
>> PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
>>
>
>
>
> --
> *--*
> *Atte.-*
> *Brunhilde M. Ojeda Sibeth*
>

--
*--*
*Atte.-*
*Brunhilde M. Ojeda Sibeth*

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Miguel Beltran R. 2018-02-10 02:56:30 Re: Suma de columna en una semana
Previous Message Néstor Ramires 2018-02-09 12:37:01 Re: Permisos para usuario por columnas