Ir al contenido


Foto

Que aparezca la fila con un SUM en cero


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

#1 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 07 junio 2013 - 09:59

Buenas, tengo un dilema, he aquí la consulta


Select s.forma_envio, COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
From SUSCRIPCIONES s
Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
and s.ESTADO_SCIONES = 'A'
and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
and s.cod_sucursal = 1
Group by s.forma_envio
Order by s.forma_envio asc


Las formas de envío pueden ser de tres tipos posibles: CORREO, ESTAFETA, RETIRA
La consulta me dice cuantos ejemplares van por cada uno de los tipos, el resultado: tres filas

CORREO    10
ESTAFETA  13
RETIRA      20

El drama se me presenta cuando uno de los tipos no tiene ejemplares en el rango de fechas, supongamos que ESTAFETA no tiene ejemplares en el rango de fechas, lo que yo quiero que presente es:

CORREO    10
ESTAFETA  0
RETIRA      20

Sin embargo, la sql me devuelve

CORREO    10
RETIRA      20

¿Cómo puedo hacer para lograr que ponga ESTAFETA  0?

Gracias, Santiago.
  • 0

#2 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 418 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 07 junio 2013 - 10:18

has revisado si en realidad hay registros que contengan el tipo de envio "ESTAFETA"  ?
  • 0

#3 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 07 junio 2013 - 10:24

has revisado si en realidad hay registros que contengan el tipo de envio "ESTAFETA"  ?


Por lo que entiendo es que NO existe registro de ESTAFETA, es por eso que desea que aparezca, pero en 0, como referencia de que no se generaron envíos por ese medio...

Se me ha ocurrido que puedas hacerle un UNION de tal manera que si el registro no se muestra en tu consulta principal (que es la que nos muestras) obligues a que se muestre con el UNION... en ese caso, harías tres UNION's (1 consulta principal y 3 alternas, uno para cada medio CORREO, ESTAFETA y RETIRA)

Esto se complica si los medios de envío aumentan (estoy suponiendo que siempre son 3), pero de momento no se me ocurre otra solución...

:embarrassed:

Saludox ! :)
  • 0

#4 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 07 junio 2013 - 10:25

Mmmm, pensando en otra opción, y si en vez de filas, generas una columna forzosa para cada medio de envío y la sumatoria en cada columna ???

^o| ^o| ^o| ^o| ^o|

Se me ocurre, no sé...

Saludox ! :)
  • 0

#5 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 07 junio 2013 - 10:27

has revisado si en realidad hay registros que contengan el tipo de envio "ESTAFETA"  ?


No, justamente. En cierto rango de fechas no hay registros con ese tipo de  envío. Pero yo necesito que muestre (que me diga) que ese tipo de envío no tiene ejemplares.


  • 0

#6 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 07 junio 2013 - 10:30

Mmmm, pensando en otra opción, y si en vez de filas, generas una columna forzosa para cada medio de envío y la sumatoria en cada columna ???

^o| ^o| ^o| ^o| ^o|

Se me ocurre, no sé...

Saludox ! :)


¿Será esto?

Select COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
From SUSCRIPCIONES s
Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
and s.ESTADO_SCIONES = 'A'
and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
and s.cod_sucursal = 1
Group by s.forma_envio


Me sale igual, solamente las que son distintas de cero.
  • 0

#7 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 418 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 07 junio 2013 - 10:32

yo haria algo asi, tendia una tabla que contenga las formas de envio, (COD_ENVIO, FORMA_ENVIO), entonces hago un simple select de la tabla e ingreso la sumatoria de los movimientos de fomra anidada algo asi:

SELECT A.FORMA_ENVIO,
(
SELECT COALESCE(SUM(s.CANT_EJEMPLARES), 0)
FROM SUSCRIPCIONES s
WHERE (s.TIPO_SCIONES = 'PAPEL' OR s.TIPO_SCIONES = 'PAPEL E INTERNET')
AND s.ESTADO_SCIONES = 'A'
AND '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
AND s.cod_sucursal = 1
AND S.COD_ENVIO = A.COD_ENVIO
) AS CANT_RESERVA
FROM FENVIOS A


  • 0

#8 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 07 junio 2013 - 10:37

Bien, lo que propones está bueno, lamentablemente no tengo una tabla con las formas de envío y la cosa es medio complicada para ponerla.
Hice lo siguiente:

Select COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS CORREO,
  (Select COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
  From SUSCRIPCIONES s
  Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
  and s.ESTADO_SCIONES = 'A'
  and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
  and s.cod_sucursal = 1
  and s.forma_envio = 'RETIRA') AS RETIRA,

  (Select COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
  From SUSCRIPCIONES s
  Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
  and s.ESTADO_SCIONES = 'A'
  and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
  and s.cod_sucursal = 1
  and s.forma_envio = 'ESTAFETA') AS ESTAFETA

From SUSCRIPCIONES s
Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
and s.ESTADO_SCIONES = 'A'
and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
and s.cod_sucursal = 1
and s.forma_envio = 'CORREO'
Group by s.forma_envio


Que es algo parecido que lo que sugieres y me sale siempre un renglón pero con tres columnas "forzadas", si es positivo, no hay drama, si es cero me sale un null que puedo hacer un rebusque para que sea el "cero"


  • 0

#9 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 418 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 07 junio 2013 - 10:42

Bien, lo que propones está bueno, lamentablemente no tengo una tabla con las formas de envío y la cosa es medio complicada para ponerla.
Hice lo siguiente:


Select COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS CORREO,
  (Select COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
  From SUSCRIPCIONES s
  Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
  and s.ESTADO_SCIONES = 'A'
  and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
  and s.cod_sucursal = 1
  and s.forma_envio = 'RETIRA') AS RETIRA,

  (Select COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
  From SUSCRIPCIONES s
  Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
  and s.ESTADO_SCIONES = 'A'
  and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
  and s.cod_sucursal = 1
  and s.forma_envio = 'ESTAFETA') AS ESTAFETA

From SUSCRIPCIONES s
Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
and s.ESTADO_SCIONES = 'A'
and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
and s.cod_sucursal = 1
and s.forma_envio = 'CORREO'
Group by s.forma_envio


Que es algo parecido que lo que sugieres y me sale siempre un renglón pero con tres columnas "forzadas", si es positivo, no hay drama, si es cero me sale un null que puedo hacer un rebusque para que sea el "cero"



hay que agregar un COALESCE sobre el COALESCE principal
  • 0

#10 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 07 junio 2013 - 10:47


Mmmm, pensando en otra opción, y si en vez de filas, generas una columna forzosa para cada medio de envío y la sumatoria en cada columna ???

^o| ^o| ^o| ^o| ^o|

Se me ocurre, no sé...

Saludox ! :)


¿Será esto?

Select COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
From SUSCRIPCIONES s
Where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET')
and s.ESTADO_SCIONES = 'A'
and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
and s.cod_sucursal = 1
Group by s.forma_envio


Me sale igual, solamente las que son distintas de cero.


No, al final en esa consulta estás prácticamente haciendo lo mismo que la primera solución que mostraste... más bien me refería a:


select '1' as sucursal,
    (select coalesce(sum(x.cant_ejemplares),0)
        from suscripciones x
    where x.forma_envio = 'ESTAFETA'
        and (x.TIPO_SCIONES = 'PAPEL' or x.TIPO_SCIONES = 'PAPEL E INTERNET'
        and x.ESTADO_SCIONES = 'A'
        and '2013/06/08' BETWEEN x.f_inic_sciones AND x.f_fin_sciones
        and x.cod_sucursal = 1) as ESTAFETA,
    (select coalesce(sum(x.cant_ejemplares),0)
        from suscripciones x
    where x.forma_envio = 'CORREO'
        and (x.TIPO_SCIONES = 'PAPEL' or x.TIPO_SCIONES = 'PAPEL E INTERNET'
        and x.ESTADO_SCIONES = 'A'
        and '2013/06/08' BETWEEN x.f_inic_sciones AND x.f_fin_sciones
        and x.cod_sucursal = 1) as CORREO,
    (select coalesce(sum(x.cant_ejemplares),0)
        from suscripciones x
    where x.forma_envio = 'RETIRA'
        and (x.TIPO_SCIONES = 'PAPEL' or x.TIPO_SCIONES = 'PAPEL E INTERNET'
        and x.ESTADO_SCIONES = 'A'
        and '2013/06/08' BETWEEN x.f_inic_sciones AND x.f_fin_sciones
        and x.cod_sucursal = 1) as RETIRA
from suscripciones s
where (s.TIPO_SCIONES = 'PAPEL' or s.TIPO_SCIONES = 'PAPEL E INTERNET'
and s.ESTADO_SCIONES = 'A'
and '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
and s.cod_sucursal = 1


La idea es que resulte algo como:

sucursal  estafeta    correo    retira
    1              0              10          20

Tal vez la consulta no esté optimizada, sería cuestión de modificarla para que no se vuelva lenta, pero con la misma idea....

Saludox ! :)


  • 0

#11 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 07 junio 2013 - 10:49

Jejejeje, veo que han colocado una consulta con subconsultas, similar a mi propuesta...

:angel:

Saludox ! :)
  • 0

#12 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 07 junio 2013 - 12:38

Saludos.

Creo que esta consulta pudiera funcionar para lo que andas buscando:
SELECT DISTINCT S.FORMA_ENVIO, 0 AS CANT_RESERVA
FROM SUSCRIPCIONES S
UNION ALL
SELECT s.forma_envio, COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
FROM SUSCRIPCIONES s
WHERE (s.TIPO_SCIONES = 'PAPEL' OR s.TIPO_SCIONES = 'PAPEL E INTERNET')
AND s.ESTADO_SCIONES = 'A'
AND '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
AND s.cod_sucursal = 1
GROUP BY s.forma_envio
ORDER BY 1


Ojo: Prueba  con UNION ALL o UNION.
  • 0

#13 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 07 junio 2013 - 02:54

Si la DB es Firebird, esto te debería funcionar:


SELECT
          SUM(CORREOS) AS TOTAL_CORREO,
          SUM(ESTAFETAS) AS TOTAL_ESTAFETA,
          SUM(RETIRAS) AS TOTAL_RETIRA
FROM
(SELECT
          IIF(s.forma_envio = 'CORREO', s.CANT_EJEMPLARES, 0)  AS CORREOS,
          IIF(s.forma_envio= 'ESTAFETA', s.CANT_EJEMPLARES, 0)  AS ESTAFETAS ,
          IIF(s.forma_envio= 'RETIRA', s.CANT_EJEMPLARES, 0)  AS RETIRAS
FROM SUSCRIPCIONES s
WHERE (s.TIPO_SCIONES = 'PAPEL' OR s.TIPO_SCIONES = 'PAPEL E INTERNET')
AND s.ESTADO_SCIONES = 'A'
AND '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
AND s.cod_sucursal = 1
ORDER BY s.forma_envio ASC)


Saludos
  • 0

#14 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 07 junio 2013 - 05:17

Saludos.

Creo que esta consulta pudiera funcionar para lo que andas buscando:

SELECT DISTINCT S.FORMA_ENVIO, 0 AS CANT_RESERVA
FROM SUSCRIPCIONES S
UNION ALL
SELECT s.forma_envio, COALESCE(SUM(s.CANT_EJEMPLARES), 0) AS cant_reserva
FROM SUSCRIPCIONES s
WHERE (s.TIPO_SCIONES = 'PAPEL' OR s.TIPO_SCIONES = 'PAPEL E INTERNET')
AND s.ESTADO_SCIONES = 'A'
AND '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
AND s.cod_sucursal = 1
GROUP BY s.forma_envio
ORDER BY 1


Ojo: Prueba  con UNION ALL o UNION.


Esta funciona bien, con UNION o UNION ALL.
Solamente que siempre sale una fila (la primera) vacía y con cant = 0; algo que no sería un gran problema.

Gracias...
  • 0

#15 santiago14

santiago14

    Advanced Member

  • Miembros
  • PipPipPip
  • 334 mensajes
  • LocationCerrillos - Salta - Argentina

Escrito 07 junio 2013 - 05:20

Si la DB es Firebird, esto te debería funcionar:


SELECT
          SUM(CORREOS) AS TOTAL_CORREO,
          SUM(ESTAFETAS) AS TOTAL_ESTAFETA,
          SUM(RETIRAS) AS TOTAL_RETIRA
FROM
(SELECT
          IIF(s.forma_envio = 'CORREO', s.CANT_EJEMPLARES, 0)  AS CORREOS,
          IIF(s.forma_envio= 'ESTAFETA', s.CANT_EJEMPLARES, 0)  AS ESTAFETAS ,
          IIF(s.forma_envio= 'RETIRA', s.CANT_EJEMPLARES, 0)  AS RETIRAS
FROM SUSCRIPCIONES s
WHERE (s.TIPO_SCIONES = 'PAPEL' OR s.TIPO_SCIONES = 'PAPEL E INTERNET')
AND s.ESTADO_SCIONES = 'A'
AND '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
AND s.cod_sucursal = 1
ORDER BY s.forma_envio ASC)


Saludos


Funciona bien pero cuando una forma de envío no tiene ejemplares, me devuelve null. En este caso, al estar en columnas, el null puedo hacerlo valer como un cero cuando lo agarro en Delphi.
  • 0

#16 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 07 junio 2013 - 08:28

Funciona bien pero cuando una forma de envío no tiene ejemplares, me devuelve null. En este caso, al estar en columnas, el null puedo hacerlo valer como un cero cuando lo agarro en Delphi.

Entonces prueba así:


SELECT
          COALESCE(SUM(CORREOS),0) AS TOTAL_CORREO,
          COALESCE(SUM(ESTAFETAS,0) AS TOTAL_ESTAFETA,
          COALESCE(SUM(RETIRAS),0) AS TOTAL_RETIRA
FROM
(SELECT
          IIF(s.forma_envio = 'CORREO', s.CANT_EJEMPLARES, 0)  AS CORREOS,
          IIF(s.forma_envio= 'ESTAFETA', s.CANT_EJEMPLARES, 0)  AS ESTAFETAS ,
          IIF(s.forma_envio= 'RETIRA', s.CANT_EJEMPLARES, 0)  AS RETIRAS
FROM SUSCRIPCIONES s
WHERE (s.TIPO_SCIONES = 'PAPEL' OR s.TIPO_SCIONES = 'PAPEL E INTERNET')
AND s.ESTADO_SCIONES = 'A'
AND '2013/06/08' BETWEEN s.f_inic_sciones AND s.f_fin_sciones
AND s.cod_sucursal = 1
ORDER BY s.forma_envio ASC)

  • 0




IP.Board spam blocked by CleanTalk.