PDA

Ver la Versión Completa : como sumar con nulos?


lledesma
02-09-2008, 04:01:44
Hola comunidad:

Recurro a uds por que puedo dar con la solucion:
tengo p.e. 3 registros
idcliente - mes - condicion importe
1 1 N 100
1 1 null -50
1 1 null -20


y tengo que obtener

1 1 N 30
Utilizo firebird 2.0 y es en un procedimiento almacenado

Actualmente uso:
Código SQL [-] (http://www.clubdelphi.com/foros/#) select idcliente,mes,condicion,sum(importe) from cuentas group by idcliente,mes,condicion


obtengo
1 1 N 100
1 1 null -70

Muchas gracias

egostar
02-09-2008, 04:33:28
Hola


select idcliente,mes,coalesce(condicion, 'N'),sum(importe) from cuentas
group by idcliente,mes,condicion


Aqui solo mi pregunta, solo tienes N o son mas condiciones, si son mas condiciones no creo que haya algo que nos sirva.

Salud OS

Caro
02-09-2008, 04:38:21
Hola lledesma, si colocas en tu group by condición, así como estan tus datos se van a formar dos grupos uno de los que tiene N y el otro de los nulos, que sería lo normal, si quieres un solo grupo debes quitar condición.


select idcliente,mes,sum(importe) from cuentas group by idcliente,mes


Saluditos

lledesma
02-09-2008, 15:36:12
Gracias por las respuestas:

Gracias Caro y Egostar: si, en realidad tengo mas condiciones. Los nulos me generan un problema, no puedo obtener el saldo por clientes y necesito saber la condicion por cada mes.

hecospina
02-09-2008, 22:05:12
select idcliente,mes,coalesce(CAMPO,'N'),sum(importe) from cuentas group by idcliente,mes,condicionYo creo que lo que te sugiere egostar esta bien si se considera que lo que se adiciona en le coalesce no es una codicion sino un campoLo que hace el coalesce es darle un valor el que se quiera, en este caso 'N' para los registros que vienen nulos, los demas valores los asigna como estan en la base de datos:)

lledesma
03-09-2008, 14:54:30
Gracias ecospina, el problema es que al utilizar coalesce(CAMPO,'N') me sirve en la mediada que CAMPO tenga el valor 'N', si CAMPO viene con otro valor?.

tcp_ip_es
03-09-2008, 15:36:12
Lo que tienes que tener claro es que valor le quieres dar a los Null, en el caso que todos los Null los asumas como N, lo que te ha puesto egostar es correcto, en el caso que tengas por ejemplo valores N , valores X y valores Nulos y estes agrupando por ese campo, Null será otra agrupación más como N y X. Si quieres puedes utilizar condicionales y preguntar si es nulo y en ese caso darle un valor u otro.....

hecospina
03-09-2008, 21:11:26
Para aclarte
La funsion de Coalesce es como lo dice Tcp_ip.., reemplaza los valores nulos por le que tu quieras, cuando le campo viene con un valor la consulta respeta dicho valor
Lo que se coloca antes de la coma no es una condicion, es el campo que estas llamando

ejemplo

sin coalesce

SELECT CAMPO1,CAMPO2,CAMPO3
from tabla

campo1---------campo2----------campo3
valor1-----------A----------------NULL
Valor2-----------b----------------DIA
Valor3-----------c----------------NOCHE
Valor4-----------d----------------NULL


CON COALESCE

SELECT CAMPO1,CAMPO2,COALESCE(CAMPO3,'NO DEFINIDO') AS Campo3
from tabla

campo1---------campo2----------campo3
valor1-----------A----------------NO DEFINIDO
Valor2-----------b----------------DIA
Valor3-----------c----------------NOCHE
valor1-----------d----------------NO DEFINIDO

:)

egostar
03-09-2008, 21:20:11
Efectivamente,

La funcion coalesce te "cambia" los valores nulos por lo que tu gustes y mandes, en este caso yo los asigne a 'N' dada tu primer intervencion


tengo p.e. 3 registros
idcliente - mes - condicion importe
1 1 N 100
1 1 null -50
1 1 null -20

y tengo que obtener

1 1 N 30


Incluso te pregunté si solo eran condiciones de tipo 'N', para lo cual la solución funcionará a la perfección, sin embargo, al tener varias condiciones tu debes decidir a cual condición quieres asignarla o como dicen los compañeros, crear una condición adicional.

Salud OS

lledesma
05-09-2008, 14:24:31
Muchas gracias gente por los aportes:

Bien, ahora entiendo como funciona coalesce, pero creo que no sirve para mis propositos. Deberia saber con que valor viene el campo "condicion" para poder asignar el valor que corresponda de modo de poder sumarlo todo en un solo registro, y como las condiciones puden ser todas la que el usuario defina, se complica.


select idcliente,coalesce(condicion,'??'),sum(importe) from cuentas group by idcliente,condicion


esto deberia darme un solo registro

1------------N---------20; donde N pude ser cualquier letra


Gracias de nuevo

hach
05-09-2008, 18:57:02
Hola Luis
De lo que decis no entiendo lo siguiente

Bien, ahora entiendo como funciona coalesce, pero creo que no sirve para mis propositos. Deberia saber con que valor viene el campo "condicion" para poder asignar el valor que corresponda de modo de poder sumarlo todo en un solo registro, y como las condiciones puden ser todas la que el usuario defina, se complica.



donde decis
Deberia saber con que valor viene el campo "condicion" para poder asignar el valor que corresponda de modo de poder sumarlo todo en un solo registro

Sabés con que valor viene el campo condicion, una letra o null...
no podes agrupar letras con null, que sentido tiene? si estan en null es porque no son N...

Tenes que definir un criterio para agrupar...
si es por cliente-mes-condicion los null te van a aparecer separados, no hay otra forma de que aparezcan...

Lo que vos estas queriendo hacer es agrupar solo por cliente-mes, y con sacar condicion de la consulta alcanza

en tu ejemplo pusiste:

1 1 N 100
1 1 null -50
1 1 null -20
y tengo que obtener
1 1 N 30

Por que queres que los null te aparezcan agrupados con las N ????
Si son null no son N...

Saca la condicion de la consulta para que quede
1 1 100
1 1 -50
1 1 -20
y obtendras
1 1 30

No se si te entendi...
espero te sirva esto

Saludos
Pablo

egostar
05-09-2008, 19:09:57
Pues si, conincido con hach

En realidad no hay lógica en tu pregunta, como pretendes conocer algo que no trae una condición. :confused::eek:

Salud OS

lledesma
05-09-2008, 21:39:24
Es verdad, no es muy logico mi planteo y quizas no fue clara mi pregunta.
el registro que tiene la condicion e importe positivo, hace referencia a una factura y los registros con null y negativos a los distintos pagos que hizo el cliente. es real que hay una falla en el diseño del sistema ya que deberia grabar la condicion tanto en la factura como en los pagos, pero como se trata de una archivo historico, ya arrastra este error. Es por eso que necesito saber por cada mes el saldo y la condicion que tenia el cliente en ese mes asumiento que los nullos tienen que tener el valor de la condicion correspondiente a la factura. Se entiende?. Ademas necesito saber l condicion por que dependiendo del valor que tenga ('N','M','C',...etc) dispara una serie de calculos adicionales

Gracia nuevamente por la buena disposicion.

egostar
05-09-2008, 21:50:27
Ok, eso ya esta mas o menos claro

Vamos por partes

Que condición deberian tener los valores negativos?
Como podemos saber los otros tipos de condiciones?

Salud OS

lledesma
07-09-2008, 14:42:22
Ok.

Los valores negativos deberian tener la misma condicion de la factura (valores positivos) para el mes en cuention. p.e.

mes------------condicion------importe
1-----------------N------------- 100
1-----------------null----------- -30
1-----------------NULL---------- -10
1-----------------NULL---------- -10

esto deberia dar

1-------------------N------------ 50

Las condiciones estan en una tabla de condiciones:

condicion------- descripcion
N--------------- "xxxxxxxxxxxxxx"
M--------------- "yyyyyyyyyyyy"
B---------------- "zzzzzzzzzzzzzz"

Intente con este provedimiento almacenado, pero en unat tabla con 250000 registros demora una eternidad.

for select idcliente,ano,mes
sum(importe) as importe from cuentas
group by idcliente,ano,mes
INTO :idcliente,:ano,:mes,:importe do
begin
select distinct condicion from cuentas where idcliente=:idcliente and ANO =:ANO AND MES=:MES into :condicion;
end


Espero te sirva. Gracias

egostar
07-09-2008, 14:52:05
Hola

Creo que el que no ha entendido el asunto eres tu, nos sigues poniendo el ejemplo de la condicion N y nulos, y despues hablas de otras condiciones, pero no nos has puesto un ejemplo con todas las condiciones.


mes------------condicion------importe
1-----------------N------------- 100
1-----------------null----------- -30
1-----------------NULL---------- -10
1-----------------NULL---------- -10
1-----------------M------------- 100
1-----------------null----------- -30
1-----------------NULL---------- -10
1-----------------NULL---------- -10
1-----------------B------------- 100
1-----------------null----------- -30
1-----------------NULL---------- -10
1-----------------NULL---------- -10


Otra cosa es si estos datos vienen ordenados o no, creo que estas en un lio con la estructura que tienes, no veo como puedas con esa información tan limitada conocer a que factura pertenece cada pago si no trae una condición, un numero de factura, un numero de cliente, una fecha, en fin algo que nos permita realizar un proceso.

Salud OS

lledesma
07-09-2008, 17:03:32
Egostar, antes que nada te agradezco por el tiempo, no quiero generar una discusion sin final, si el problema no llega a nada o no se entiende, punto final. El tema es: la facturas, importes positivos, pueden "venir" con cualquier condicion (siempre que esten definidas en las tablas de condicion) y es la que domina sobre los importes negativos para ese mes. pe.

idcliente -------mes------------ condicion-----------importe
5---------------1-----------------M----------------- 100
5---------------1-----------------null--------------- -30
5---------------1-----------------null--------------- -20
5---------------2-----------------B----------------- 70
5---------------2-----------------null--------------- -20
5---------------2-----------------null--------------- -10
5---------------3-----------------C---------------- 40
5---------------3-----------------null-------------- -5

deberia obtener

5---------------1------------------M----------------- 50
5---------------2------------------B----------------- 40
5---------------3------------------C----------------- 35

si pudiera hacer que

select idcliente,mes,condicion,sum(importe) from cuentas group by idcliente,mes,condicion


me sumara los nulos como M o B o C o ... etc segun el mes y la condicion del valor positivo seria fantástico.

Con respecto a los otros datos, la estructura es mas compleja, tiene numero de factura,tipo de comprobantes, fecha, etc. Pero consideré que era demasiado engorroso ponerla en el ejemplo, me importaba solo la idea como para poder aplicarla sobre el modelo de datos



Gracias.

Caral
07-09-2008, 17:39:07
Hola
Lo que no entiendo es por que dejar nulos en la tabla?.
La verdad me parece que siempre trae problemas, yo prefiero poner algo, lo que sea pero no dejar el espacio en blanco.
Saludos

ninguno
07-09-2008, 18:43:10
Hola

Lo que no entiendo es por que dejar nulos en la tabla?.
La verdad me parece que siempre trae problemas, yo prefiero poner algo, lo que sea pero no dejar el espacio en blanco.

A ver, NULL es un valor como cualquier otro. ¿Qué más da que ponga NULL a que ponga "-" o a que ponga ""? Con esos valores tendría el mismo problema, B o C o M sería diferente de ese valor que tu pusieras por defecto.

La cuestión está en poder sumar todos los valores de un determinado mes. Si sólo puede haber una condición por mes, la cosa es sencilla, el problema vendría si se puede dar más de una condición por mes ya que no sabríamos donde asignar esos valores a NULL (o con el valor por defecto que quieras).

Si suponemos que sólo se puede dar una condición por mes, el SQL podría quedar algo así:

select distinct c1.idcliente, c1.mes, c1.condicion
(select sum(importe) from cuentas c2
where c2.idcliente = c1.idcliente and c2.mes = c1.mes) importe
from cuentas c1
where not (c1.condición is NULL)


El SQL no lo he probado, pero sería así más o menos y, repito, SÓLO serviría para el caso de que sólo se pudiera tener una condición por mes.

egostar
08-09-2008, 03:09:52
A ver, NULL es un valor como cualquier otro. ¿Qué más da que ponga NULL a que ponga "-" o a que ponga ""? Con esos valores tendría el mismo problema, B o C o M sería diferente de ese valor que tu pusieras por defecto.


Acaso hemos dicho lo contrario ????



La cuestión está en poder sumar todos los valores de un determinado mes. Si sólo puede haber una condición por mes, la cosa es sencilla, el problema vendría si se puede dar más de una condición por mes ya que no sabríamos donde asignar esos valores a NULL (o con el valor por defecto que quieras).


:D, Insisto, hemos dicho lo contrario????


Si suponemos que sólo se puede dar una condición por mes, el SQL podría quedar algo así:


:D:D, Pues por desgracia hemos estado suponiendo todo este tiempo muchas cosas, el problema es que no se nos pone la información necesaria para llegar a una solución.......


Con respecto a los otros datos, la estructura es mas compleja, tiene numero de factura,tipo de comprobantes, fecha, etc. Pero consideré que era demasiado engorroso ponerla en el ejemplo, me importaba solo la idea como para poder aplicarla sobre el modelo de datos


:eek::eek: Caray, pues te has y nos has liado demasiado con algo que puede verse y solucionarse desde otra perspectiva.

Salud OS

ninguno
08-09-2008, 13:26:38
Hola

Acaso hemos dicho lo contrario ????

Sí, fíjate mi cita de Caral ;)


:D:D, Pues por desgracia hemos estado suponiendo todo este tiempo muchas cosas, el problema es que no se nos pone la información necesaria para llegar a una solución.......


Como he dicho, si en un mes puede haber más de 1 tipo de condición y no todos los registros están informados, será difícil, por no decir imposible, hacer esa suma dado que NO podrás saber a qué condición agregarle esos registros sin condición.

lledesma
08-09-2008, 16:04:25
Perdon si generé lios, no era mi intencion. Igual gracias por los aportes. Y me corrijo, El resto de informacion que falta en los datos no tiene relevancia, por cuanto no sirve a los propositos que busco, el ejemplo que pongo a consideración es tal cual se utiliza en el procedimiento. De nuevo, gracias

gmontes
08-09-2008, 16:17:20
Hola comunidad:

Recurro a uds por que puedo dar con la solucion:
tengo p.e. 3 registros
idcliente - mes - condicion importe
1 1 N 100
1 1 null -50
1 1 null -20


y tengo que obtener

1 1 N 30
Utilizo firebird 2.0 y es en un procedimiento almacenado

Actualmente uso:
Código SQL [-] (http://www.clubdelphi.com/foros/#) select idcliente,mes,condicion,sum(importe) from cuentas group by idcliente,mes,condicion


obtengo
1 1 N 100
1 1 null -70

Muchas gracias


si la condicion no importa, solo quitala del select y del group

Caro
08-09-2008, 16:41:20
si la condicion no importa, solo quitala del select y del group

Ahí esta el problema la condición si importa, como he dicho al principio, con esta consulta.


select idcliente, mes, sum(importe) from cuentas group by idcliente,mes


ya obtenemos lo que el amigo quiere


5 1 M 50
5 2 B 40
5 3 C 35


pero no sabemos a que condición pertenece cada uno de esos registros, ahora si aumentamos en el group by la condición, obtrendremos este resultado ya que nos va a agrupar por ese campo mas.


5 1 null -50
5 1 M 100
5 2 null -30
5 2 B 70
5 3 null -5
5 3 C 35


y es lo que no se quiere, entonces la pregunta sería como añadir mas campos en una consulta con group by pero sin colocarlo en el group by para que no afecte en la agrupación. De hecho si utilizamos group by y queremos mostrar un campo en el select tenemos que añadirlo en el group by.

La verdad yo también quisiera saber como hacer eso.

Saluditos

Caral
08-09-2008, 16:56:04
Hola
A mi no me hagáis caso, de estas cosas no se, solo opino.
Saludos

gmontes
08-09-2008, 16:59:39
el problema es que

tiene lo siguiente:

1 1 N 100
1 1 null -50
1 1 null -20

y quiere obtener 1 1 N 30

select idcliente,mes,condicion,sum(importe) from cuentas group by idcliente,mes,condicion

obtiene
1 1 N 100
1 1 null -70

lo cual es valido porque agrupa por por condicion

o sea que si la condicion fuera por B

1 1 B 200
1 1 N 100
1 1 null -50
1 1 null -20

el quisiera obtener
1 1 B 130

es decir, que las condiciones Null se sumen a cualquier condicion que se seleccione.

pues que en el procedure tenga dos select

select idcliente,mes,condicion,sum(importe) from cuentas where condicion = "N" group by idcliente,mes,condicion



y la segunda

select idcliente,mes,condicion,sum(importe) from cuentas where condicion is NULL group by idcliente,mes,condicion

y que los campos de salida del importe sea la suma de ambas condiciones

Caro
08-09-2008, 17:12:50
Te endiendo amiguito GMontes, pero si nos fijamos en los datos que nos puso si sabemos a donde pertenecen los null, los registros en rojo le pertenecen al mes 1, los verdes al mes 2 y el azul al mes 3, por eso decía que con la agrupación de solo cliente y condición ya obtenemos lo que queremos.


idcliente -------mes------------ condicion-----------importe
5---------------1-----------------M----------------- 100
5---------------1-----------------null--------------- -30
5---------------1-----------------null--------------- -20
5---------------2-----------------B----------------- 70
5---------------2-----------------null--------------- -20
5---------------2-----------------null--------------- -10
5---------------3-----------------C---------------- 40
5---------------3-----------------null-------------- -5


Acabo de hacer una prueba de esta consulta y si funciona, se obtiene lo que quiere el amigo, por lo menos a mi me funciona, pero nose que tan bien pueda estar. Lo he probado en Firebird por si acaso.


select c1.idcliente, c1.mes, c1.condicion,
(select sum(importe)
from clientes where idcliente=c1.idcliente and mes=c1.mes group by id_cliente, mes)
from clientes c1
where condicion is not Null


Saluditos

egostar
08-09-2008, 17:19:25
Hola amiguita [Caro]

Y que pasaría si en un mismo mes tiene las opciones N,M,B,C,X,Y,Z y tiene el mismo cliente varias veces.

Ahi es donde yo tengo la duda de que se pueda hacer así como lo plantea lledesma

Yo creo que hace falta mas información para poder "adivinar" este asunto.

Salud OS

Caro
08-09-2008, 17:38:11
Y que pasaría si en un mismo mes tiene las opciones N,M,B,C,X,Y,Z y tiene el mismo cliente varias veces.
Ahi es donde yo tengo la duda de que se pueda hacer así como lo plantea lledesma
Yo creo que hace falta mas información para poder "adivinar" este asunto.


En ese caso egopolice :rolleyes:, ya no funciona lo ultimo que puse, yo me he basado en el ultimo ejemplo y explicación que puso Iledesma.

Saluditos

egostar
08-09-2008, 17:41:53
En ese caso egopolice :rolleyes:, ya no funciona lo ultimo que puse, yo me he basado en el ultimo ejemplo y explicación que puso Iledesma.

Saluditos

Pues si, me parece que el buen amigo lledesma nos está dando las cosas a cuenta gotas :D

Salud ITOS

PD, Apurale que ya veo que varios tienen ganas de festejar a un nuevo milenario :)

maeyanes
08-09-2008, 17:46:23
Hola...

Hola amiguita [Caro]

Y que pasaría si en un mismo mes tiene las opciones N,M,B,C,X,Y,Z y tiene el mismo cliente varias veces.

Ahi es donde yo tengo la duda de que se pueda hacer así como lo plantea lledesma

Yo creo que hace falta mas información para poder "adivinar" este asunto.

Salud OS

Pues según entiendo (y a lo mejor entiendo mal :p), para cada mes solo puede existir una condición con valor (importes positivos) y varias nulas (importes negativos), de tal forma que, si entendí bien, la consulta de Caro debería servir bien...


Saludos...

Caro
08-09-2008, 17:59:05
PD, Apurale que ya veo que varios tienen ganas de festejar a un nuevo milenario :)

Espero llegar mañana amiguito :), muchas gracias por fijarte ;).

Saluditos

hach
08-09-2008, 18:39:47
Hola otra vez!!!
A ver si entendi:
1) la factura tiene una condicion y un importe
2) los pagos tienen importes pero no condicion

es asi?

La unica forma de hacer lo que querés es saber la condicion de los pagos, y como no la tienes, la unica forma sería si podés vincular un pago a una determinada factura
Es eso posible? Un pago corresponde a una factura determinada? Tenés forma de vincularlos mediante los datos que tenés?
Si es así, es sencillo, basta con traer la condicion de la factura a la cual pertenece el pago en el select
Si no es asi, no le des mas vueltas...

en algun lado dices:

necesito saber por cada mes el saldo y la condicion que tenia el cliente en ese mes asumiento que los nullos tienen que tener el valor de la condicion correspondiente a la factura
La condicion es propia del cliente?
Podrias vincular el cliente con el pago, y obtener la condicion
pero si cambia de mes a mes, solo obtendrias la ultima condicion, salvo que lleves un historico de condiciones...



Saludos

Pablo

Delphius
08-09-2008, 19:41:59
Yo todavía no comprendo bien lo que busca (por empezar que no me queda totalmente claro como está estructurada la tabla) y esquivé al hilo lo más que pude.
Me acerco ahora a preguntarle, o aconsejarle (no me decido si es una duda o o un consejo) ¿Consideraste estructurar la tabla y/o la información de otra manera? ¿Podríamos conocer mejor la estructura de tus tablas?

Saludos,

lledesma
08-09-2008, 23:52:09
Hola a todos

Creo que Caro es la que resumio un poco lo que no supe explicar

cita:

...y es lo que no se quiere, entonces la pregunta sería como añadir mas campos en una consulta con group by pero sin colocarlo en el group by para que no afecte en la agrupación. De hecho si utilizamos group by y queremos mostrar un campo en el select tenemos que añadirlo en el group by...


La estructura esta armada de ese modo y no puede modificarla.
Cada cliente puede tener solo una factura por mes con cualquier tipo de condicion y sus respectivos pagos, valores negativos, estan asociados a la factura por idcliente,ano,mes.

La informacion no se va dando a cuenta gotas, se hace conforme a la discusion de este foro.

egostar
09-09-2008, 00:07:45
Creo que Caro es la que resumio un poco lo que no supe explicar


Pues nuestra amiguita [Caro] te lo dijo desde el post # 3 (http://www.clubdelphi.com/foros/showpost.php?p=310999&postcount=3) de este hilo. :confused::confused:


La informacion no se va dando a cuenta gotas, se hace conforme a la discusion de este foro.


:rolleyes::rolleyes::rolleyes:

Salud OS

Caral
09-09-2008, 01:09:01
Hola
Me canso y no me dais la solución, a ver si os apuráis.:D:D
Saludos

Caro
09-09-2008, 04:59:28
Cada cliente puede tener solo una factura por mes con cualquier tipo de condicion y sus respectivos pagos, valores negativos, estan asociados a la factura por idcliente,ano,mes.


Con cualquier tipo de condición pero no con dos o mas condiciones para el mismo mes, si he entendido bien, entoces Iledesma la ultima consulta que te puse debería funcionarte, pruebala, es esta.


select c1.idcliente, c1.mes, c1.condicion,
(select sum(importe)
from clientes where idcliente=c1.idcliente and mes=c1.mes group by id_cliente, mes)
from clientes c1
where condicion is not Null


Saluditos

hach
09-09-2008, 13:37:44
Me canso y no me dais la solución, a ver si os apuráis.:D:D
Saludos

A pedido de Caral, aca va un aporte

Se me ocurre crear un view


CREATE VIEW CLIENTES_VIEW(
IDCLIENTE,
MES,
CONDICION,
IMPORTE)
AS
select c.idcliente, c.mes, c.condicion, c.importe
from clientes c
where c.condicion is not null
union
select c.idcliente, c.mes
, (select c2.condicion from clientes c2 where c2.condicion is not null and c2.idcliente=c.idcliente and c2.mes=c.mes)
, c.importe
from clientes c
where c.condicion is null
;


y despues hacer el select sobre el view



select idcliente, mes, condicion, sum(importe)
from clientes_view
group by idcliente, mes, condicion
order by idcliente, mes



Saludos

lledesma
10-09-2008, 19:28:17
Muchas gracias por los aporte.

Tengo un problema con mi firebird, pero pruebo y les comento.
Gracias