Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Reporte

Estas en el tema de Reporte en el foro de Mysql en Foros del Web. Buenos dias, espero poder explicarme este reporte como parametro me pide solo la fecha final y al generarlo sale el reporte desde el primer dia ...
  #1 (permalink)  
Antiguo 18/06/2012, 09:32
 
Fecha de Ingreso: noviembre-2007
Mensajes: 37
Antigüedad: 16 años, 5 meses
Puntos: 0
Reporte

Buenos dias, espero poder explicarme este reporte como parametro me pide solo la fecha final y al generarlo sale el reporte desde el primer dia del mes hasta la fecha final que uno ingresa. Y mi pregunta es como puedo hacer que en este mismo reporte salgan el total de galones pero desde el primer dia del mes hasta un dia antes de la fecha final que uno ingresa?

Código:
DELIMITER $$

DROP PROCEDURE IF EXISTS `usp_Consolidado` $$
CREATE DEFINER=`tomza`@`%` PROCEDURE `usp_Consolidado`(
         in pFechaFinal varchar(50)


)
BEGIN

DROP TABLE IF EXISTS Tmp;
CREATE TABLE Tmp


SELECT factura.fecha as fecha,personal.codigo as codigo, concat(personal.nombres, ' ', personal.apellidos) nombre,distribucion.nombre as distribucion,
if(articulo.codigo='2005', factura_detalle.cantidad,0) as CL05,
if(articulo.codigo='2010', factura_detalle.cantidad,0) as CL10,
if(articulo.codigo='2020', factura_detalle.cantidad,0) as CL20,
if(articulo.codigo='2025', factura_detalle.cantidad,0) as CL25,
if(articulo.codigo='2035', factura_detalle.cantidad,0) as CL35,
if(articulo.codigo='2040', factura_detalle.cantidad,0) as CL40,
if(articulo.codigo='2060', factura_detalle.cantidad,0) as CL60,
if(articulo.codigo='2100', factura_detalle.cantidad,0) as CL100,



if(articulo.codigo='2005' or articulo.codigo='2010' or articulo.codigo='2020' or articulo.codigo='2025'
or articulo.codigo='2035' or articulo.codigo='2040' or articulo.codigo='2060' or  articulo.codigo='2100',factura_detalle.cantidad,0)  as cilingaldros,

if(articulo.codigo='2005' or articulo.codigo='2010' or articulo.codigo='2020' or articulo.codigo='2025'
or articulo.codigo='2035' or articulo.codigo='2040' or articulo.codigo='2060' or  articulo.codigo='2100',factura_detalle.galones,0) as equival_galones,

if(articulo.codigo='4000' or articulo.codigo='5000',factura_detalle.galones,0) as galones


from factura_detalle
inner join factura on factura_detalle.facturaid=factura.facturaid
inner join personal on factura.pilotoid=personal.personalid
inner join distribucion on factura.distribucionid=distribucion.distribucionid
inner join articulo on factura_detalle.articuloid=articulo.articuloid where articulo.codigo='2005' or articulo.codigo='2010' or articulo.codigo='2020'
or articulo.codigo='2025' or articulo.codigo='2035' or articulo.codigo='2040' or articulo.codigo='2060' or articulo.codigo='2100' or articulo.codigo='4000' or articulo.codigo='5000';

select date_format(fecha, '%Y/%m/%d'),codigo, nombre,distribucion,
(sum(CL05) + sum(CL10)) as OTROS, sum(CL20) as CL20, sum(CL25) as CL25, sum(CL35) as CL35, sum(CL40) as CL40, sum(CL60) as CL60,
sum(CL100) as CL100,
sum(cilingaldros) as cilingaldros, sum(equival_galones) as equival_galones, sum(galones) as galones



from tmp c

where
      date_format(fecha, '%Y/%m/%d') between date_format(pFechaFinal,'%Y/%m/01') and   date_format(pFechaFinal,'%Y/%m/%d')
group by codigo order by fecha;


END $$

DELIMITER ;
  #2 (permalink)  
Antiguo 18/06/2012, 10:15
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Reporte

Mira, técnicamente lo único que necesitas es usar una de las funciones de fecha que MySQL tiene, para restar un día al límite del rango.
Código MySQL:
Ver original
  1. DATE_SUB(fecha, INTERVAL 1 DAY);
Pero eso mismo lo podrías hacer antes de enviar el parámetro en tu programa y el resultado sería el mismo...
De hecho, es mejor dejar que eso lo maneje el programa, y no meterlo en el SP, porque de esa forma el SP mantendría la flexibilidad que de otro modo le quitarías (todas las llamadas siempre te devolverían hasta la fecha anterior al límite).
Fuera de eso, no hay impedimentos.

Ahora bien, a mi me intriga una cosa: ¿Por qué usas DATE_FORMAT()?
Código MySQL:
Ver original
  1. date_format(fecha, '%Y/%m/%d') between date_format(pFechaFinal,'%Y/%m/01') and   date_format(pFechaFinal,'%Y/%m/%d')
Si ya tienes la fecha como un DATE o DATETIME (el DATE_FRMAT() no sirve con otros campos), ¿por qué razón quieres transformar eso en una cadena de texto, que bien te pede producir resultados erróneos?

¿Me lo puedes aclarar?


Por cierto: si el código es numérico, no deberías compararlo como cadena de texto. Eso puede reducir a performace por generar cantidades ingentes de conversiones implícitas, que no se necesitan:
Código MySQL:
Ver original
  1. articulo.codigo='4000' or articulo.codigo='5000'
contra
Código MySQL:
Ver original
  1. articulo.codigo=4000 or articulo.codigo=5000
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 18/06/2012, 10:23
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Reporte

Hola palmach:

Iba a contestar prácticamente lo mismo que gnzsoloyo (otra vez se me adelantó ), pero me gustaría enfatizar un punto, que creo que respondería la pregunta de gnzsoloyo:

NUNCA, PERO NUNCA DEBES UTILIZAR FECHAS COMO VARCHAR, tu parámetro de entrada pFechaFinal lo estás declarando como tipo varchar(50)

Código:
CREATE DEFINER=`tomza`@`%` PROCEDURE `usp_Consolidado`(
  in pFechaFinal varchar(50)
)
Aquí más que preguntar por que utilizas DATE_FORMAT la pregunta sería ¿POR QUÉ NO PONES TU PARÁMETRO DE ENTRADA COMO TIPO DATE O DATETIME?

Saludos
Leo.
  #4 (permalink)  
Antiguo 18/06/2012, 10:30
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Reporte

Cierto, Leonardo. Yo ni miré los parámetros de entrada porque asumí que serian DATEo DATETI'E. Ni en sueños se me ocurriría que ponía otra cosa... ::S:
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 18/06/2012, 10:40
 
Fecha de Ingreso: noviembre-2007
Mensajes: 37
Antigüedad: 16 años, 5 meses
Puntos: 0
Respuesta: Reporte

Tienen toda la razon gnzsoloyo y leonardo_josue ya hice los cambios gracias,
ahora con eso lo de DATE_SUB(fecha, INTERVAL 1 DAY); si lo entendi ahora como lo pongo para que me de el resultado de galones del primer dia del mes hasta un dia antes de la fecha final y tambien q me de el resultado de galones pero solo lo de la fecha final en el mismo reporte?


Código:
DELIMITER $$

DROP PROCEDURE IF EXISTS `usp_Consolidado` $$
CREATE DEFINER=`tomza`@`%` PROCEDURE `usp_Consolidado`(
         in pFechaFinal datetime


)
BEGIN

DROP TABLE IF EXISTS Tmp;
CREATE TABLE Tmp


SELECT factura.fecha as fecha,personal.codigo as codigo, concat(personal.nombres, ' ', personal.apellidos) nombre,distribucion.nombre as distribucion,
if(articulo.codigo=2005, factura_detalle.cantidad,0) as CL05,
if(articulo.codigo=2010, factura_detalle.cantidad,0) as CL10,
if(articulo.codigo=2020, factura_detalle.cantidad,0) as CL20,
if(articulo.codigo=2025, factura_detalle.cantidad,0) as CL25,
if(articulo.codigo=2035, factura_detalle.cantidad,0) as CL35,
if(articulo.codigo=2040, factura_detalle.cantidad,0) as CL40,
if(articulo.codigo=2060, factura_detalle.cantidad,0) as CL60,
if(articulo.codigo=2100, factura_detalle.cantidad,0) as CL100,



if(articulo.codigo=2005 or articulo.codigo=2010 or articulo.codigo=2020 or articulo.codigo=2025
or articulo.codigo=2035 or articulo.codigo=2040 or articulo.codigo=2060 or  articulo.codigo=2100,factura_detalle.cantidad,0)  as cilingaldros,

if(articulo.codigo=2005 or articulo.codigo=2010 or articulo.codigo=2020 or articulo.codigo=2025
or articulo.codigo=2035 or articulo.codigo=2040 or articulo.codigo=2060 or  articulo.codigo=2100,factura_detalle.galones,0) as equival_galones,

if(articulo.codigo=4000 or articulo.codigo=5000,factura_detalle.galones,0) as galones


from factura_detalle
inner join factura on factura_detalle.facturaid=factura.facturaid
inner join personal on factura.pilotoid=personal.personalid
inner join distribucion on factura.distribucionid=distribucion.distribucionid
inner join articulo on factura_detalle.articuloid=articulo.articuloid where articulo.codigo=2005 or articulo.codigo=2010 or articulo.codigo=2020
or articulo.codigo=2025 or articulo.codigo=2035 or articulo.codigo=2040 or articulo.codigo=2060 or articulo.codigo=2100 or articulo.codigo=4000 or articulo.codigo=5000;

select fecha,codigo, nombre,distribucion,
(sum(CL05) + sum(CL10)) as OTROS, sum(CL20) as CL20, sum(CL25) as CL25, sum(CL35) as CL35, sum(CL40) as CL40, sum(CL60) as CL60,
sum(CL100) as CL100,
sum(cilingaldros) as cilingaldros, sum(equival_galones) as equival_galones, sum(galones) as galones



from tmp c

where
      fecha between date_format(pFechaFinal,'%Y/%m/01') and   date_format(pFechaFinal,'%Y/%m/%d')
group by codigo order by fecha;


END $$

DELIMITER ;
  #6 (permalink)  
Antiguo 18/06/2012, 12:06
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Reporte

Hola de nuevo palmach:

En realidad estás hablando de dos consultas distintas, es decir en una estás involucrando rangos de fechas, por lo tanto la condición de filtrado del WHERE debería quedar así:

Código:
WHERE
  fecha BETWEEN
  DATE_FORMAT(pFechaFinal,'%Y/%m/01') AND
  DATE_SUB(pFechaFinal, INTERVAL 1 DAY);
Para que te arroje sólo lo de la fecha final en el mismo reporte no deberías utilizar BETWEEN, sino simplemente hacer una igualación:

Código:
WHERE
  fecha  = pFechaFinal;
De una vez que comento que no puedes hacer un WHERE CONDICIONAL, por si estás pensando en que se ponga una condición u otra... lo que puedes hacer en todo caso sería utilizar una sentencia preparada la cual construyas de manera dinámica y en donde decidas a partir de una condición qué condición incluir:

http://dev.mysql.com/doc/refman/5.0/es/sqlps.html

Otra alternativa en su defecto sería tener dos procedimientos almacenados distintos, uno para el rango y otro para una fecha en concreto.

Saludos
Leo.
  #7 (permalink)  
Antiguo 19/06/2012, 08:40
 
Fecha de Ingreso: noviembre-2007
Mensajes: 37
Antigüedad: 16 años, 5 meses
Puntos: 0
Respuesta: Reporte

Gracias a los dos, use la alternativa de leonardo_josue en usar dos procedimientos y ya con eso salio lo que necesito.

Saludos,

Etiquetas: join, reporte, select
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:36.