Ver Mensaje Individual
  #8 (permalink)  
Antiguo 08/11/2013, 20:11
Avatar de gnzsoloyo
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, 5 meses
Puntos: 2658
Respuesta: Ejecutar consulta si cumple condicion

Estoy mirando con más cuidado el código, y francamente hay algunas cosas que no le veo mucho sentido, e incluso que pueden tener resultados un tanto irreales o falsos.
Tomemos una de las consultas (todas son mas o menos similares), y analicemos un par de cosas:
Código MySQL:
Ver original
  1.     e.id_ser,
  2.     emp.nombre_razonsocial,
  3.     CONCAT(p.Apellidos,'-',p.Nombres) 'Nombres',
  4.     e.fecha,
  5.     TIME(e.fecha_Entrada) 'Entrada',
  6.     TIME(e.fecha_Salida_Almuerzo) 'Salida_Almuerzo',
  7.     TIME (e.fecha_Entrada_Almuerzo) 'Entrada_Almuerzo',
  8.     SEC_TO_TIME(SUM((TIME_TO_SEC(e.fecha_Entrada_Almuerzo) - TIME_TO_SEC(e.fecha_Salida_Almuerzo)))) 'Total_Almuerzo',
  9.     TIME (e.fecha_salida) 'Salida_Laboral',
  10.     SEC_TO_TIME(SUM((TIME_TO_SEC(e.fecha_Salida) - TIME_TO_SEC(e.fecha_Entrada)))) 'Total_Labor'
  11. FROM eventos e
  12.     INNER JOIN personas p ON e.id_ser=p.id_ser
  13.     INNER JOIN  personas_empresa pe ON e.id_ser=pe.id_ser
  14.     INNER JOIN  empresas emp ON pe.id_empresa=emp.id_empresa
  15.     fecha BETWEEN fecha1 AND fecha2
  16.     AND  emp.id_empresa=3
  17. GROUP BY e.id_ser, e.fecha ASC WITH ROLLUP
  18. LIMIT 2000;
Por lo pronto estás agrupando por sólo dos columnas de ocho, pero de esas solo dos están afectadas por funciones agregas. Lo que significa que las seis restantes pueden tener resultados irreales, ya que el GROUP BY tomará el primer valor que encuentre en la tabla y esconderá el resto. El que pongas ASC en la fecha es medio irrelevante, porque ese ASC no aplicará a esos otros cuatro campos, con lo que si bien la fecha puede ser del ultimo registro, el nombre, la razon social, las entradas y salidas, serán los primeros registros encontrados, aunque no coincidan con esos otros.
Pero le agregas agrupar por evento, por el ID de evento, con lo cual, además implicará que te devolverá un registro por cada registro de evento, y como cada uno de esos registros se corresponde a horas de entrada y salida, entonces el GROUP BY termina sin tener efectos en esos items,

Estas son sólo algunas de las observaciones a hacer. A esta debo agregar al menos tres cosas:

- Primero, en los SP existen clausulas para controlar el flujo, tales como CASE, por lo que no tiene ningún sentido usar IFs. Además, en lugar de hacer tantos anidamientos, podrías haber usado el ELSEIF, que es más lineal.

- En segundo lugar, no alcanzo a percibir mayores diferencias entre las distintas consultas, a excepción del valor de id_empresa, usado en el IF, con lo que en la mayoría de los casos deberías haber usado el parámetro, en lugar de harcodear innecesariamente el valor. tendrías posiblemente una única consulta, algo más dinámica. Hay, si, una consulta distinta, pero eso podria entrar en un ELSE sin problemas.

Sería magnífico que nos expliques exactamente qué tipo de resumen de datos se supone que obtienes, para verificar si realmente esa sintaxis cumple lo que tu deseas.

Por lo pronto, yo la plantearía así:
Código MySQL:
Ver original
  1. DELIMITER $$
  2.  
  3. CREATE PROCEDURE MICONSULTA(IN fecha1 DATE, fecha2 DATE,Grupo INT)
  4.  
  5.     IF Grupo > 0 THEN
  6.         SELECT
  7.             eventos.nombre_razonsocial,
  8.             eventos.id_ser,
  9.             eventos.Nombres,
  10.             IFNULL(eventos.fecha, 'RESULTADO TOTAL SOCIO DE NEGOCIOS') FECHA,
  11.             eventos.Entrada,
  12.             eventos.Salida_Almuerzo,
  13.             eventos.Entrada_Almuerzo,
  14.             eventos.Total_Almuerzo,
  15.             eventos.Salida_Laboral,
  16.             eventos.Total_Labor
  17.         FROM
  18.             (SELECT  
  19.                 e.id_ser,
  20.                 emp.nombre_razonsocial,
  21.                 CONCAT(p.Apellidos,'-',p.Nombres) 'Nombres',
  22.                 e.fecha,
  23.                 TIME(e.fecha_Entrada) 'Entrada',
  24.                 TIME(e.fecha_Salida_Almuerzo) 'Salida_Almuerzo',
  25.                 TIME (e.fecha_Entrada_Almuerzo) 'Entrada_Almuerzo',
  26.                 SEC_TO_TIME(SUM((TIME_TO_SEC(e.fecha_Entrada_Almuerzo) - TIME_TO_SEC(e.fecha_Salida_Almuerzo)))) 'Total_Almuerzo',
  27.                 TIME (e.fecha_salida) 'Salida_Laboral',
  28.                 SEC_TO_TIME(SUM((TIME_TO_SEC(e.fecha_Salida) - TIME_TO_SEC(e.fecha_Entrada)))) 'Total_Labor'
  29.             FROM eventos e
  30.                 INNER JOIN personas p ON e.id_ser=p.id_ser
  31.                 INNER JOIN  personas_empresa pe ON e.id_ser=pe.id_ser
  32.                 INNER JOIN  empresas emp ON pe.id_empresa=emp.id_empresa
  33.             WHERE
  34.                 fecha BETWEEN fecha1 AND fecha2
  35.                 AND  emp.id_empresa = Grupo
  36.             GROUP BY e.id_ser, e.fecha ASC WITH ROLLUP
  37.     ELSE
  38.         SELECT
  39.             eventos.nombre_razonsocial,
  40.             eventos.id_ser,
  41.             eventos.Nombres,
  42.             IFNULL(eventos.fecha, 'RESULTADO TOTAL SOCIO DE NEGOCIOS') FECHA,
  43.             eventos.Entrada,
  44.             eventos.Salida_Almuerzo,
  45.             eventos.Entrada_Almuerzo,
  46.             eventos.Total_Almuerzo,
  47.             eventos.Salida_Laboral,
  48.             eventos.Total_Labor
  49.         FROM
  50.             (SELECT  
  51.                 e.id_ser,
  52.                 emp.nombre_razonsocial,
  53.                 CONCAT(p.Apellidos,'-',p.Nombres) 'Nombres',
  54.                 e.fecha,
  55.                 TIME(e.fecha_Entrada) 'Entrada',
  56.                 TIME(e.fecha_Salida_Almuerzo) 'Salida_Almuerzo',
  57.                 TIME (e.fecha_Entrada_Almuerzo) 'Entrada_Almuerzo',
  58.                 SEC_TO_TIME(SUM((TIME_TO_SEC(e.fecha_Entrada_Almuerzo) - TIME_TO_SEC(e.fecha_Salida_Almuerzo)))) 'Total_Almuerzo',
  59.                 TIME (e.fecha_salida) 'Salida_Laboral',
  60.                 SEC_TO_TIME(SUM((TIME_TO_SEC(e.fecha_Salida) - TIME_TO_SEC(e.fecha_Entrada)))) 'Total_Labor'
  61.             FROM eventos e
  62.                 INNER JOIN personas p ON e.id_ser=p.id_ser
  63.                 INNER JOIN  personas_empresa pe ON e.id_ser=pe.id_ser
  64.                 INNER JOIN  empresas emp ON pe.id_empresa=emp.id_empresa
  65.             WHERE fecha BETWEEN fecha1 AND fecha2
  66.             GROUP BY e.id_ser,e.fecha ASC WITH ROLLUP
  67.             LIMIT 2000) eventos;
  68.     END IF;
  69. END$$
  70. DELIMITER ;
O mejor aún, lo intentaría con sentencias preparadas:
Código MySQL:
Ver original
  1. DELIMITER $$
  2.  
  3. CREATE PROCEDURE MICONSULTA(IN fecha1 DATE, fecha2 DATE,Grupo INT)
  4.     SET @qry = '';
  5.     SET @fecha1 = NOW();
  6.     SET @fecha2 = NOW();
  7.    
  8.     SET @qry = 'SELECT
  9.            eventos.nombre_razonsocial,
  10.            eventos.id_ser,
  11.            eventos.Nombres,
  12.            IFNULL(eventos.fecha, ''RESULTADO TOTAL SOCIO DE NEGOCIOS'') FECHA,
  13.            eventos.Entrada,
  14.            eventos.Salida_Almuerzo,
  15.            eventos.Entrada_Almuerzo,
  16.            eventos.Total_Almuerzo,
  17.            eventos.Salida_Laboral,
  18.            eventos.Total_Labor
  19.        FROM
  20.            (SELECT  
  21.                e.id_ser,
  22.                emp.nombre_razonsocial,
  23.                CONCAT(p.Apellidos,'-',p.Nombres) Nombres,
  24.                e.fecha,
  25.                TIME(e.fecha_Entrada) Entrada,
  26.                TIME(e.fecha_Salida_Almuerzo) Salida_Almuerzo,
  27.                TIME (e.fecha_Entrada_Almuerzo) Entrada_Almuerzo,
  28.                SEC_TO_TIME(SUM((TIME_TO_SEC(e.fecha_Entrada_Almuerzo) - TIME_TO_SEC(e.fecha_Salida_Almuerzo)))) 'Total_Almuerzo',
  29.                TIME (e.fecha_salida) Salida_Laboral,
  30.                SEC_TO_TIME(SUM((TIME_TO_SEC(e.fecha_Salida) - TIME_TO_SEC(e.fecha_Entrada)))) Total_Labor
  31.            FROM eventos e
  32.                INNER JOIN personas p ON e.id_ser=p.id_ser
  33.                INNER JOIN  personas_empresa pe ON e.id_ser=pe.id_ser
  34.                INNER JOIN  empresas emp ON pe.id_empresa=emp.id_empresa
  35.            WHERE
  36.                fecha BETWEEN ? AND ? ';
  37.     IF qry; > 0 THEN
  38.         SET @qry = CONCAT(@qry;, ' AND  emp.id_empresa = ? ');
  39.     END IF
  40.     SET @qry; = CONCAT(@qry;, ' GROUP BY e.id_ser, e.fecha ASC WITH ROLLUP');
  41.     SET @fecha1 = fecha1;
  42.     SET @fecha2 = fecha2;
  43.     SET @grupo = Grupo;
  44.    
  45.     PREPARE stmt1 FROM @query;
  46.    
  47.     IF Grupo > 0 THEN
  48.         EXECUTE stmt1 USING @fecha1, @fecha2, @grupo;
  49.     ELSE
  50.         EXECUTE stmt1 USING @fecha1, @fecha2;
  51.     END IF;
  52.     DEALLOCATE @qry;
  53.    
  54. END$$
  55. DELIMITER ;

Habría que probarlo...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)