Buenos dias: Una respuesta, larga, te voy desarrollando cosas.
On Fri, Dec 18, 2015 at 8:44 PM, ViBaSoft <vibas...@gmail.com> wrote: > Quiero sacar el precio minimo, máximo, media por mes por columna y una > general, en la general me sale bien pero por mes columna no me trae el > minimo. Me trae 0(cero) siempre en la columna min_enero Tu problema es el clasico de mal valor por defecto. Estas haciendo el MIN de una columna de precios ( >=0 ) con un 0 cuando no es enero, con lo que te sale 0: > MIN(CASE WHEN extract(month from c.fecha_factura)=1 THEN cd.preciocompra > ELSE 0 END) AS precio_min_enero, En cuanto una fila de febrero entra el el case da 0, el minimo es 0. Prueba a poner un numero enorme en el else, no se cual decirte ya que no has puesto el esquema de la tabla pero siendo precios si pones 'ELSE 999999999999999999' te deberia valer. Esa es la solucion clasica usada cuando calculas un minimo corrido en un lenguaje clasico, inicializar el minimo al nuero mas largo que puedas y si el valor leido es menor, actualizr ( min=99999999, if curr<min then min=curr ) ). En SQL puedes ademas hacer una mas astuta, ya que min filtra los nulos, unos ejemplos, tu query actual con unos datos de pruebas: s=> select min(case when mes=1 then precio else 0 end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); min ----- 0 (1 row) La solucion con el 999999999: cdrs=> select min(case when mes=1 then precio else 999999999 end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); min ----- 2.0 (1 row) Que tiene un problema si no hubiera datos de enero, por ejemplo para el mes 3 pasa esto: cdrs=> select min(case when mes=3 then precio else 999999999 end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); min ----------- 999999999 (1 row) Que es necesario controlar fuera de banda, si en lugar de 9999999 usas null te viene un null de resultado: cdrs=> select min(case when mes=3 then precio else null end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); min ----- (1 row) Que es mas facil de distinguir. Comprobamos que el caso del 1 sigue funcioanado igual: cdrs=> select min(case when mes=1 then precio else null end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); min ----- 2.0 (1 row) Y ademas el null vale tambien para max: cdrs=> select max(case when mes=1 then precio else null end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); max ----- 3.0 (1 row) E incluso para avg, sum y count: cdrs=> select avg(case when mes=1 then precio else null end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); avg -------------------- 2.5000000000000000 (1 row) cdrs=> select count(case when mes=1 then precio else null end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); count ------- 2 (1 row) cdrs=> select sum(case when mes=1 then precio else null end) from ( values(1,2.0),(1,3.0),(2,1.0),(2,4.0)) as datos(mes,precio); sum ----- 5.0 (1 row) Lo que te simplificaria bastante tu query, y lo deja, IMHO, mas claro, ya que en SQL el NULL se ve enseguida como 'falta dato' o 'dato desconocido' o 'no procede'. Incluso, aprovechando que el null propaga, puedes hacerlo en dos partes, primero sacas una columna con los datos de enero luego agregas. Como usas una version EOL no voy ni a intentar hacerte una prueba real que no se si funcionara, no voy a ir buscando documentaciones historicas, pero seria algo asi. Tabla extendida: SELECT cd.codigo as codigo, cd.cantidad as cant, preciocompra, (CASE WHEN extract(month from c.fecha_factura)=1 THEN cd.cantidad ELSE NULL END) AS cant_enero, (CASE WHEN extract(month from c.fecha_factura)=1 THEN cd.preciocompra ELSE NULL END) AS precio_enero FROM compras cd inner join compra c on cd.idcompras=c.idcompras WHERE trim(cd.codigo)='90-131-00-00001' and c.fecha_factura>='2015-01-01' Y luego puedes agregar con eso: select codigo, sum(cant) as cant, min(preciocompra) as min_precio, max(preciocompra) as max_precio, sum(cant_enero) as cant_enero, min(precio_enero) as min_precio_enero, max(precio_enero) as max_precio_enero, sum(precio_enero*cant_enero)/sum(precio_enero) as media_enero FROM (** LO DE ARRIBA**) as extendida GROUP BY codigo. ****** > Trabajo con porstgres 9.0 Esa version esta EOL, yo que tu iria mirando de actualizar. De hecho el query de ejemplo te lo hubiera puesto con WITH pero ni recuerdo si lo soportaba en esa version. Francisco Olarte. - Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda@postgresql.org) Para cambiar tu suscripci�n: http://www.postgresql.org/mailpref/pgsql-es-ayuda