Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 05-11-2017
netcom netcom is offline
Miembro
NULL
 
Registrado: nov 2014
Posts: 11
Poder: 0
netcom Va por buen camino
Sumar y restar campos agrupados por otro campo

Buenas a todos,

Os escribo después de mucho buscar a ver si podéis iluminarme con mi problema. Lo intentaré exponer lo mejor posible, si necesitarais otra información me indicáis.

Dada la siguiente tabla de ejemplo;

TABLAMOVIMIENTOS:

Cuenta--------Movimiento---Cantidad----Articulo
Empresa 1------Entrada---------3-----------X
Empresa 1------Entrada---------7-----------X
Empresa 1------Salida-----------5-----------X
Empresa 1------Entrada---------6-----------Y
Empresa 1------Salida-----------3-----------Y
Empresa 2------Entrada---------4-----------X
Empresa 2------Entrada---------4-----------X
Empresa 2------Salida-----------3-----------X
Empresa 2------Entrada---------5-----------Y
Empresa 2------Salida-----------1-----------Y

Necesito realizar una sentencia SQL que me muestre el Total de cantidades restando de Entradas-Salidas y agrupadas por Cuenta según un artículo dado. Por ejemplo,

Si lo hiciera para el artículo X, busco el siguiente resultado:

Total Artículos X empresa 1 =3+7-5 = 5
Total Artículos X empresa 2 = 4+4-3 = 5

Lo mismo si hiciera la búsqueda para el artículo Y:

Total Artículos Y empresa 1 = 6-3 = 3
Total Artículos Y empresa 2 = 5-1 = 4

Hasta ahora, he llegado a la siguiente sentencia SQL:

Código Delphi [-]
with datamodule1.AQ_Movimientos do
          Begin
            Close;
            SQL.Clear;
            SQL.Add('Select Cuenta, ((SELECT SUM(Cantidad) from TablaMovimientos WHERE Articulo= "Entrada") - ');
            SQL.Add('(SELECT SUM(Cantidad) from TablaMovimientos WHERE Articulo= "Salida")) AS TOTAL');
            SQL.Add('FROM TablaMovimientos WHERE articulo =:referencia and tipoRegistro = "Entrada" group by Cuenta');
            Parameters.ParamByName('referencia').Value:=Edit_Artículo.text;
            OPEN;
          End;

Tras ejecutarla no da error, pero el resultado no es el que quiero, para la tabla anterior me da siempre lo siguiente (sea cual sea al artículo), hace la suma-resta de toda la tabla y me da un totalizado por cuentas:

Si lo hago para un artículo X:

Total Artículos X empresa 1 = 3+7-5 +4+4-3 = 10
Total Artículos X empresa 2 = 3+7-5 +4+4-3 = 10

Y si lo hago para un artículo Y:

Total Artículos Y empresa 1 = 6-3+5-1 = 7
Total Artículos Y empresa 2 = 5-1+6-3 = 7

También he probado la misma sentencia añadiendo el parámetro artículo el la suma, pero en ese caso, el resultado de la sentencia es ninguno:

Código Delphi [-]
with datamodule1.AQ_Movimientos do
          Begin
            Close;
            SQL.Clear;
            SQL.Add('Select Cuenta, ((SELECT SUM(Cantidad) from TablaMovimientos WHERE Articulo= "Entrada") - ');
            SQL.Add('(SELECT SUM(Cantidad) from TablaMovimientos WHERE Articulo= "Salida")) AS TOTAL');
            SQL.Add('FROM TablaMovimientos WHERE articulo =:referencia and tipoRegistro = "Entrada" group by Cuenta');
            Parameters.ParamByName('referencia').Value:=Edit_Artículo.text;
            OPEN;
         End;

Alguna idea para conseguir lo que busco?!?!
Utilizo delphi XE2

Gracias por adelantado!!!
Responder Con Cita
  #2  
Antiguo 06-11-2017
Avatar de TOPX
TOPX TOPX is offline
Miembro
 
Registrado: may 2008
Ubicación: Bogotá
Posts: 527
Poder: 16
TOPX Va camino a la fama
Buenas.

Para probar, partí de la siguiente estructura:
Código SQL [-]
CREATE TABLE movimiento (
  cuenta INTEGER,
  tipo VARCHAR(1),
  cantidad INTEGER,
  articulo VARCHAR(1)
);

INSERT INTO movimiento VALUES (1, 'E', 3, 'X');
INSERT INTO movimiento VALUES (1, 'E', 7, 'X');
INSERT INTO movimiento VALUES (1, 'S', 5, 'X');
INSERT INTO movimiento VALUES (1, 'E', 6, 'Y');
INSERT INTO movimiento VALUES (1, 'S', 3, 'Y');
INSERT INTO movimiento VALUES (2, 'E', 4, 'X');
INSERT INTO movimiento VALUES (2, 'E', 4, 'X');
INSERT INTO movimiento VALUES (2, 'S', 3, 'X');
INSERT INTO movimiento VALUES (2, 'E', 5, 'Y');
INSERT INTO movimiento VALUES (2, 'S', 1, 'Y');

Solamente cambiando unos pequeños detalles a la original, para hacer más comprensibles las consultas.

No dice qué motor de base de datos está utilizando; así que con uno convencional, bastaría con algo como:
Código SQL [-]
SELECT 
  cuenta, 
  SUM(
    CASE 
      WHEN tipo = 'S' THEN cantidad*(-1) 
      ELSE cantidad 
    END
  ) AS total
FROM movimiento
WHERE articulo = 'Y'
GROUP BY cuenta
Es decir, condicionando la suma según el valor de un campo, para que tome valores negativos o positivos.

Y ya. Se puede probar en ~ http://sqlfiddle.com/#!7/9d125/13

Pero, según sus mensajes anteriores sospecho que está utilizando Microsoft Access. Por lo que, averigüé por ahí que ese software no soporta la sentencia CASE usada anteriormente.

Entonces, lo instalé en una máquina virtual desechable y aprendí a traducir a una consulta equivalente:
Código SQL [-]
SELECT
  cuenta, 
  SUM(
    SWITCH(
      tipo = 'S', cantidad*(-1),
      tipo = 'E', cantidad
    ) 
  ) AS total
FROM movimiento
WHERE articulo = 'Y'
GROUP BY cuenta
En todo caso, es posible que obtenga los mismos resultados con un adefesio como:
Código SQL [-]
SELECT
  a.cuenta,
  ((SELECT 
    SUM(b.cantidad)
  FROM movimiento b
  WHERE a.cuenta = b.cuenta
    AND a.articulo = b.articulo
    AND b.tipo = 'E') -
  (SELECT 
    SUM(c.cantidad)
  FROM movimiento c
  WHERE a.cuenta = c.cuenta
    AND a.articulo = c.articulo
    AND c.tipo = 'S')) AS total
FROM movimiento a
WHERE a.articulo = 'Y'
GROUP BY a.cuenta, a.articulo
Que se podría llamar: la espeluznante franken-consulta. Pero, a cada quien con sus gustos.
-
__________________
"constructive mind, destructive thoughts"
Responder Con Cita
  #3  
Antiguo 06-11-2017
netcom netcom is offline
Miembro
NULL
 
Registrado: nov 2014
Posts: 11
Poder: 0
netcom Va por buen camino
Muchas gracias Topx, esta tarde/ noche hago pruebas e informo del resultado.

Última edición por Casimiro Notevi fecha: 06-11-2017 a las 11:03:29.
Responder Con Cita
  #4  
Antiguo 06-11-2017
netcom netcom is offline
Miembro
NULL
 
Registrado: nov 2014
Posts: 11
Poder: 0
netcom Va por buen camino
Probado y funcionando a la perfección con SWITCH.

Muchisimas Grácias Topx!!
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Sumar el valor de campos en campo calculado fwhite Varios 3 21-02-2012 15:01:56
Restar/Sumar entre DBGrid's Lenny Varios 5 02-07-2010 14:54:13
Restar, Sumar varios registros a la vez Lenny Varios 2 28-05-2010 21:38:30
restar/sumar 3 meses a un datetimepicker Milperrimo Varios 3 17-11-2007 01:50:16
Sumar y restar fechas SMTZ .NET 3 28-11-2006 04:15:27


La franja horaria es GMT +2. Ahora son las 12:01:29.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi