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.casan...@2ndquadrant.com> escribió: > >> 2018-02-08 11:40 GMT-05:00 Brunhilde Sibeth <bruma13sib...@gmail.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*