Hola Ruben, pudieras usar una CTE (WITH) para obtener un resumen como todos tu valores agrupados por lo que planteas, es decir tendrías un max, avg,min por detalle de día:

select extract (MONTH..),extract (WEEK..),extract (DOY..),cliente,max() as maximodia ,avg() as promediodia,min() as minimomodia from tabla where
    current_date-fecha<=365*group by 1,2,3,4

y luego obtener con las Funciones Ventanas los demás valores por el PARTITION indicado:

select cliente, dia, mes, anio, maximodia, max (maximodia) OVER (PARTITION by mes) ,max (maximoanio) OVER (PARTITION by anio),......... FROM lo_del_WITH

Tal vez no es la solución, ando filosofando sin datos reales, pero te puede dar una idea de como resolverlo.

Un ejemplo que me cree con 50 datos, que puede orientarte sobre lo que puedes hacer:

create table tabla (fecha  date, importe int, cliente int);

insert into tabla
SELECT  current_date-'1 day'::INTERVAL * floor(random()*(100-1)+1) as fecha,
floor(random()*(100-1)+1) as importe,
floor(random()*(10-1)+1) as cliente
FROM generate_series(1,50) order by 3;



with subconsulta as (
select extract (MONTH from fecha) as mes ,extract (WEEK from fecha) as semana,extract (DOY from fecha) as diaa,cliente, max(importe) as maximodia ,avg(importe) as promediodia,min(importe) as minimomodia from tabla
    group by 1,2,3,4)
select cliente, diaa, mes, semana, maximodia, max (maximodia) OVER (PARTITION by cliente,mes) as maximomes ,max (maximodia) OVER (PARTITION by cliente,semana) as maximosemana FROM subconsulta

order by 1;

a lo mejor le puedes hacer un ajuste con tu caso,


saludos


El 14/10/15 a las 03:09, Ruben Fitó escribió:
Hola,


 "puedes poner un juego de datos y la salida que esperas?"

Respondiendo a Anthony, en realidad no esperaba un formato de salida concreto, solo me imaginaba algo como:

*Cliente_1*

*max_importe_dia | max_importe_semana | max_importe_mes | min_importe_dia | min_importe_semana | min_importe_mes*

10, 12, 10, 11,.. | 100, 97, 120, 80... | 500, 498, 375, ... | 2, 5, 10, 1, 1 | ...... | ..........

*Cliente_2*
.....

Cliente_3
.....


Cada columna contiene un array con los importes de los 365 dias (max_importe_dia), 52 semanas(max_importe_semana), 12 meses(max_importe_mes), y así por cada cliente. En realidad no sé cómo representarlo, porque seria una tabla de "3 dimensiones" (bromita). ;-D . Otro modo de verlo seria obtener todas las ventas agrupadas por cliente, cosa que tendríamos un resultado enorme, y a partir de ahí ir trabajando para in agrupando con subselects, arrays, when case, etc.. Pero ahí es donde tenemos el problema, una query gigantesca y de baja optimización.

Por otro lado, referente a las respuestas de Raúl i Horacio, tenemos un entorno OLTP, pero en este caso necesitamos analizar los datos de la tabla para hacer unas pequeñas estadísticas en busca de fraudes, inconsistencias, etc.. O sea, no hace falta que sea en tiempo real. Ejecutamos la consulta con cron a la madrugada. Me parece genial la idea de las vistas materializadas, pero no tenemos permiso(por ahora) para realizar este tipo de operaciones, por lo que hemos de solucionarlo sin vistas materializadas ni tablas auxiliares.

Podemos hacer hacer una query optimizada con WITH, PARTITION, u otro método..?? Como lo ven??

Hemos pensado en un inicio en hacer un WITH con los diferentes SELECT que necesitamos, pero creo que es recorrer la tabla nuevamente por cada SELECT dentro del WITH con lo que triplicaremos el coste(eso creo).

Un saludo y gracias.






2015-10-13 17:12 GMT+02:00 Horacio Miranda <hmira...@gmail.com <mailto:hmira...@gmail.com>>:

    https://cajondesastreoracle.wordpress.com/2010/02/08/vistas-materializadas/

    Mira esto, ignoro si en postgresql existe una vista materializada
    log, de no existir, un crontab con lo que necesitas debiera servir.

    PS: Me imagino que esto es para una base de datos tipo DW, no una
    OLTP o me equivoco ?

    On 10/14/2015 3:33 AM, raul andrez gutierrez alejo wrote:

        Hola Ruben.

        si no necesita los datos en tiempo real, puede utilizar 3 vistas
        materializadas, cada una agrupada por dia
        to_char(fecha,''YYYY-MM-DD')
        ,semana to_char(fecha,''YYYY-WW') o
        to_char(fecha,''YYYY-MM-W')  y mes
        to_char(fecha,''YYYY-MM'), las vistas las puede actualizar con
        un cron
        cada madrugada o cada intervalo de tiempo de decida, así logra
        un buen
        rendimiento.


        http://www.postgresql.org/docs/9.4/static/functions-formatting.html

        El 13 de octubre de 2015, 9:21, Anthony Sotolongo
        <asotolo...@gmail.com <mailto:asotolo...@gmail.com>
        <mailto:asotolo...@gmail.com <mailto:asotolo...@gmail.com>>>
        escribió:

            Hola Ruben

            El 13/10/15 a las 10:55, Ruben Fitó escribió:

                Hola Lista,


                Tengo una duda a ver si me la podrían resolver.

                Tenemos una tabla bastante grande, donde almacenamos
            ventas.

                En esta tabla tenemos los campos *fecha*(timestamp),
            *importe* y
                *cliente*, entre otras pero que no son importantes.

                *fecha | importe | cliente*

                Lo que necesitamos son los (max, avg, min) de importe
            y  número de
                ventas agrupado por cliente, día, semana y mes,
            mirando desde
                ahora hasta un año atrás, sin tener en cuenta el
            periodo más cercano.

            No se si entendi mal o no te explicaste correctamente, lo que
            entiendo es algo como esto:

            /select extract (MONTH..),extract (week..),extract (/
            /DAY..),cliente,max,avg,min from tabla where
            current_date-//*fecha<=365*//group by 1,2,3,4/

            pero de seguro no es tan sencillo, jeje

            puedes poner un juego de datos y la salida que esperas?

            Saludos

                Dicho de otro modo, necesitamos por cada día, semana y
            mes el
                (max, avg, min) de importe por cada cliente sin tener
            en cuenta el
                mes actual(para mes), el día actual(para día) o la semana
                actual(para semana).

                Hemos realizado una gigantesca query con sub-consultas
            que no se
                entiende nada, y el costo temporal es demasiado
            elevado. Creo que
                no es conveniente mostrarla ya que os dará más dolor
            de cabeza que
                otra cosa.

                No sabemos qué puede ser más óptimo, usar with con
            subconsultas,
                usar PARTITION, u otras alternativas que no hemos pensado.

                Nos da igual si nos retorna una tabla o arrays , o
            tabla de
                arrays, jejeje, simplemente que se pueda trabajar
            fácilmente para
                poder hacer comparaciones y poder discriminar con
            algún parámetro.

                Gracias de antemano.



                --
                *Ruben Fitó *
                Software Engineer

            r.f...@ubiquat.com <mailto:r.f...@ubiquat.com>
            <mailto:j.catari...@ubiquat.com
            <mailto:j.catari...@ubiquat.com>>
            www.ubiquat.com <http://www.ubiquat.com>
            <http://www.ubiquat.com/>

                Tota la informació continguda en aquest document i
            arxius adjunts
                és CONFIDENCIAL protegida per llei de secret
            comercial. Si l'ha
                rebut per error, si us plau elimini'l i posi's en
            contacte amb
                l'emissor.

                All information contained in this document and any
            attachments are
                CONFIDENTIAL and protected under trade secret laws. If
            you receive
                this message by mistake, please delete it and notify it
                immediately to the sender.





        --
        Raul Andres Gutierrez Alejo




--
*Ruben Fitó *
Software Engineer
        Ubiquat Technologies, SL
r.f...@ubiquat.com <mailto:j.catari...@ubiquat.com>
        www.ubiquat.com <http://www.ubiquat.com/>

Tota la informació continguda en aquest document i arxius adjunts és CONFIDENCIAL protegida per llei de secret comercial. Si l'ha rebut per error, si us plau elimini'l i posi's en contacte amb l'emissor.

All information contained in this document and any attachments are CONFIDENTIAL and protected under trade secret laws. If you receive this message by mistake, please delete it and notify it immediately to the sender.

Responder a