Ir al contenido



Foto

[Firebird] Obtener el total y promedio por día de la semana


  • Por favor identifícate para responder
3 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.220 mensajes
  • LocationRepública Dominicana

Escrito 21 julio 2017 - 08:05

Estimados, estoy tratando de obtener una estadística que consiste en obtener la cantidad de despachos agrupado por día de la semana, hasta aquí bien, pero estoy teniendo problemas en obtener el promedio, intenté hacerlo a través de una consulta cross table y me he líado un montón, esto es lo que tengo:


sql
  1. SELECT
  2. COUNT(*) AS total_dias,
  3. dia,
  4. avg(cnt) AS promedio
  5. FROM
  6. (
  7. SELECT
  8. COUNT(*) AS total_dias,
  9. decode(EXTRACT(weekday FROM CAST(ot_fecha AS DATE)),
  10. 0,'DOMINGO',
  11. 1,'LUNES',
  12. 2,'MARTES',
  13. 3,'MIÉRCOLES',
  14. 4,'JUEVES',
  15. 5,'VIERNES',
  16. 6,'SÁBADO' ) AS dia,
  17. COUNT (*) AS cnt
  18. FROM
  19. ot_preventivo WHERE ot_status = 4
  20. AND CAST(ot_fecha AS DATE) BETWEEN '06.02.2017' AND '20.02.2017'
  21. GROUP BY EXTRACT(weekday FROM ot_fecha)
  22. ) AS dt
  23. GROUP BY 2

y no logro obtener los promedios, la idea que entre un rango de fecha determinar cuando despachos ha habido de acuerdo al día de la semana, o sea, entre el 10/07/2017 al 22/07/2017 debería obtener lo siguiente:

 

Dia                total_dias    despachos    promedio
LUNES              2                  50                25
MARTES            2                 112               56
MIERCOLES     2                  10                5
JUEVES             2                  11                5.5
VIERNES           2                  41                20.5

 

 

Saudos.


  • 0

#2 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 818 mensajes
  • LocationMisiones, Argentina

Escrito 26 julio 2017 - 07:56

¿Y que sale de esa consulta?

O sea, ¿qué resultado te da?

 

Vi que cnt es count(*) al igual que total_dias, es decir ambos cuentan la cantidad de filas.


Editado por cram, 26 julio 2017 - 07:59 .

  • 0

#3 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.135 mensajes

Escrito 26 julio 2017 - 10:32

Voy a "desoxidarme" mi estimado Fernando, para resolver el problema que planteas la manera mas viable a mi parecer es con procedimientos almacenados. 

Primero un SP general que devuelva las veces que se repita un día en un rango de fechas. Este SP no tiene nada que ver con tu BD, se obtiene directamente de Firebird.


sql
  1. SET TERM ^ ;
  2.  
  3. CREATE OR ALTER PROCEDURE DIAS_ENTRE_FECHAS (
  4. DIA INTEGER,
  5. INICIO DATE,
  6. FIN DATE)
  7. RETURNS (
  8. NUMERO_DIAS INTEGER)
  9. AS
  10. DECLARE variable DIFERENCIA_DIAS INTEGER;
  11. DECLARE variable CONTADOR INTEGER;
  12. DECLARE variable TEMP_DIA INTEGER;
  13. DECLARE variable VAR_DIAS INTEGER;
  14. BEGIN
  15. CONTADOR = 0;
  16. TEMP_DIA = 0;
  17. VAR_DIAS = 0;
  18.  
  19. SELECT datediff(DAY FROM :INICIO TO :FIN)
  20. FROM RDB$DATABASE
  21. INTO DIFERENCIA_DIAS;
  22.  
  23. while (CONTADOR <= DIFERENCIA_DIAS) do
  24. BEGIN
  25. SELECT EXTRACT(weekday FROM (:INICIO + :CONTADOR))
  26. FROM RDB$DATABASE
  27. INTO TEMP_DIA;
  28. IF (TEMP_DIA = :DIA) THEN
  29. VAR_DIAS = VAR_DIAS + 1;
  30. CONTADOR = CONTADOR + 1;
  31. END
  32. NUMERO_DIAS = :VAR_DIAS;
  33. END^
  34.  
  35. SET TERM ; ^

En este punto ya podemos lanzar otro SP que haga la consulta:


sql
  1. CREATE OR ALTER PROCEDURE CONSULTA (
  2. INICIO DATE,
  3. FIN DATE)
  4. RETURNS (
  5. DIA VARCHAR(10),
  6. CANTIDAD INTEGER,
  7. TOTAL_DIAS INTEGER,
  8. PROMEDIO NUMERIC(15,2))
  9. AS
  10. DECLARE variable VAR_CANTIDAD INTEGER;
  11. DECLARE variable VAR_DIA VARCHAR(10);
  12. DECLARE variable VAR_NUM_DIA INTEGER;
  13. BEGIN
  14. FOR SELECT COUNT(PK_ot_preventivo), EXTRACT(weekday FROM CAST(ot_fecha AS DATE)),
  15. CASE
  16. WHEN EXTRACT(weekday FROM CAST(ot_fecha AS DATE)) = 0 THEN 'DOMINGO'
  17. WHEN EXTRACT(weekday FROM CAST(ot_fecha AS DATE)) = 1 THEN 'LUNES'
  18. WHEN EXTRACT(weekday FROM CAST(ot_fecha AS DATE)) = 2 THEN 'MARTES'
  19. WHEN EXTRACT(weekday FROM CAST(ot_fecha AS DATE)) = 3 THEN 'MIERCOLES'
  20. WHEN EXTRACT(weekday FROM CAST(ot_fecha AS DATE)) = 4 THEN 'JUEVES'
  21. WHEN EXTRACT(weekday FROM CAST(ot_fecha AS DATE)) = 5 THEN 'VIERNES'
  22. WHEN EXTRACT(weekday FROM CAST(ot_fecha AS DATE)) = 6 THEN 'SABADO'
  23. END
  24. FROM ot_preventivo
  25. WHERE (CAST(ot_fecha AS DATE) BETWEEN :INICIO AND :FIN)
  26. AND (ot_status = 4)
  27. GROUP BY EXTRACT(weekday FROM CAST(ot_fecha AS DATE))
  28. INTO VAR_CANTIDAD, VAR_NUM_DIA, VAR_DIA
  29. do
  30. BEGIN
  31. DIA = VAR_DIA;
  32. CANTIDAD = VAR_CANTIDAD;
  33. EXECUTE PROCEDURE DIAS_ENTRE_FECHAS(VAR_NUM_DIA, INICIO, FIN)
  34. returning_values TOTAL_DIAS;
  35. PROMEDIO = CANTIDAD / TOTAL_DIAS;
  36. suspend;
  37. END
  38. END^
  39.  
  40. SET TERM ; ^

Para contar le he pasado la clave primaria de tu tabla.

 

Luego puedes llamarla en tu aplicación con una consulta muy sencilla:


sql
  1. SELECT * FROM CONSULTA(FECHA_INICIO, FECHA_FINAL)

A mi me funciona correctamente, si te atoras en algún lado me avisas.


  • 1

#4 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.220 mensajes
  • LocationRepública Dominicana

Escrito 27 julio 2017 - 10:24

Gracias Wilson!, estaré haciendo las pruebas y te comento mis resultados luego.

 

Saludos!.


  • 0