Está en la página 1de 4

26/6/2019 Columna Acumulada en SQL Server 2008

Este sitio utiliza cookies para análisis y para mostrar contenido y anuncios personalizados. Al continuar navegando por este sitio, aceptas este uso. Más información

Developer Network Iniciar sesión Suscripciones a MSDN Obtener herramientas

Descargas Programas Comunidad Documentación

Formular una pregunta Buscar conversaciones Buscar preguntas del foro


relacionadas
Acceso rápido

Principales respuestas Columna Acumulada en SQL Server 2008


Acceso a Datos > SQL Server
77,015
Pregunta
Puntos
Superior 0.1%
Buenos dias, espero me puedan ayudar:

Hunchback En mi tabla movimientos de pedido manejo un campo 'cantidad' y otro 'tipomovimiento'


MCC, MVP Se unió Mar 2008
He obtenido uniendo 2 consultas, este resultado:
Conversaciones d…
0
Inicie Producto Ingreso Salida
3 5 13 Mostrar actividad sesión
para
votar p001      200     0

p001      0        50

p001      0        70

en pocas palabras me coloca valor si en la tabla movimiento es de tipo ingreso en la columna ingreso , y 0 si
no lo es.

Quiero añadir una columna 'Acumulado' donde me tiene que mostrar de esta manera

Producto Ingreso Salida Acumulado

p001      200     0      200

p001      0        50    150

p001      0        70     80

Solo que no hallo la manera de hacerlo, los parametros que quiero ingresar desde Visual 2010 son la fecha
de inicio, fecha final y CodigoProducto, solo me falta la columna acumulado. Trabajo con SQL2008

Espero me puedan ayudar.

lunes, 9 de enero de 2012 13:25

Responder | Citar
ChrisPasache 30 Puntos

Respuestas

Esto se conoce como total corriente (running total), y hasta la version 2008 R2 la mayoria de las soluciones
basadas en conjunto, tienden a tener mal desempeño cuando el numero de filas en la tabla es un valor
significativo.

0 Entre los diferentes metodos para resolver este problema se tiene:


Inicie
sesión - Usar un cursor
para
votar - Crear una funcion de agregacion SQLCLR

- Usar un query correlacionado

- Usar JOIN consigo mismo (self join)

A partir de la nueva version 2012 (todavia no disponible en el mercado), contamos con la nueva
funcionalidad de funciones de ventanas (subclausula ROWS / RANGE en la clausula OVER), la cual nos
permite de una forma facil y legible, resolver este problema.

Dicho lo anterior, es prundente comentar que para lo que deseas hacer, se necesita un orden chronologico
de cada transaccion. Por ejemplo, como sabes que el ingreso de 200 unidades para el producto "p001"
ocurrio primero que el egreso de 150 unidades?
https://social.msdn.microsoft.com/Forums/es-ES/0b09fbbd-7542-4004-b888-4808cb28d5fd/columna-acumulada-en-sql-server-2008?forum=sqlse… 1/4
26/6/2019 Columna Acumulada en SQL Server 2008

Deberas tener una columna tipo datetime o un numero incremental, etc, que identifique cada transaccion.

Ejemplo:

DECLARE @T TABLE (
sk int NOT NULL IDENTITY (1, 1) UNIQUE CLUSTERED,
producto varchar(10) NOT NULL,
tipo_mov CHAR(1) NOT NULL CHECK (tipo_mov in ('I', 'E')),
fecha_mov datetime NOT NULL,
valor int NOT NULL CHECK (valor > 0)
);

INSERT INTO @T (producto, tipo_mov, fecha_mov, valor)


VALUES
('p001', 'I', '2012-01-01T08:30:00', 200),
('p001', 'E', '2012-01-01T08:35:00', 50),
('p001', 'E', '2012-01-01T08:40:00', 70);

SELECT
A.producto,
fecha_mov,
tipo_mov,
CASE WHEN A.tipo_mov = 'I' THEN valor ELSE 0 END AS ingreso,
CASE WHEN A.tipo_mov = 'E' THEN valor ELSE 0 END AS salida,
(
SELECT
SUM(CASE WHEN B.tipo_mov = 'I' THEN 1 ELSE -1 END * B.valor)
FROM
@T AS B
WHERE
B.producto = A.producto
AND (
B.fecha_mov < A.fecha_mov
OR
(B.fecha_mov = A.fecha_mov AND B.sk <= A.sk)
)
) AS acumulado
FROM
@T AS A
ORDER BY
A.producto,
A.fecha_mov,
A.sk;
GO

/*

producto fecha_mov tipo_mov ingreso salida acumulado


p001 2012-01-01 08:30:00.000 I 200 0 200
p001 2012-01-01 08:35:00.000 E 0 50 150
p001 2012-01-01 08:40:00.000 E 0 70 80

*/
 

AMB
Some guidelines for posting questions...

Marcado como respuesta Eduardo Portescheller Moderator miércoles, 11 de enero de 2012 12:14

lunes, 9 de enero de 2012 14:21

Responder | Citar
Hunchback Bank of America Merchant... (MCC, MVP) 77,015 Puntos

Todas las respuestas

Esto se conoce como total corriente (running total), y hasta la version 2008 R2 la mayoria de las soluciones
basadas en conjunto, tienden a tener mal desempeño cuando el numero de filas en la tabla es un valor
significativo.

https://social.msdn.microsoft.com/Forums/es-ES/0b09fbbd-7542-4004-b888-4808cb28d5fd/columna-acumulada-en-sql-server-2008?forum=sqlse… 2/4
26/6/2019 Columna Acumulada en SQL Server 2008

0 Entre los diferentes metodos para resolver este problema se tiene:


Inicie
sesión - Usar un cursor
para
votar - Crear una funcion de agregacion SQLCLR

- Usar un query correlacionado

- Usar JOIN consigo mismo (self join)

A partir de la nueva version 2012 (todavia no disponible en el mercado), contamos con la nueva
funcionalidad de funciones de ventanas (subclausula ROWS / RANGE en la clausula OVER), la cual nos
permite de una forma facil y legible, resolver este problema.

Dicho lo anterior, es prundente comentar que para lo que deseas hacer, se necesita un orden chronologico
de cada transaccion. Por ejemplo, como sabes que el ingreso de 200 unidades para el producto "p001"
ocurrio primero que el egreso de 150 unidades?

Deberas tener una columna tipo datetime o un numero incremental, etc, que identifique cada transaccion.

Ejemplo:

DECLARE @T TABLE (
sk int NOT NULL IDENTITY (1, 1) UNIQUE CLUSTERED,
producto varchar(10) NOT NULL,
tipo_mov CHAR(1) NOT NULL CHECK (tipo_mov in ('I', 'E')),
fecha_mov datetime NOT NULL,
valor int NOT NULL CHECK (valor > 0)
);

INSERT INTO @T (producto, tipo_mov, fecha_mov, valor)


VALUES
('p001', 'I', '2012-01-01T08:30:00', 200),
('p001', 'E', '2012-01-01T08:35:00', 50),
('p001', 'E', '2012-01-01T08:40:00', 70);

SELECT
A.producto,
fecha_mov,
tipo_mov,
CASE WHEN A.tipo_mov = 'I' THEN valor ELSE 0 END AS ingreso,
CASE WHEN A.tipo_mov = 'E' THEN valor ELSE 0 END AS salida,
(
SELECT
SUM(CASE WHEN B.tipo_mov = 'I' THEN 1 ELSE -1 END * B.valor)
FROM
@T AS B
WHERE
B.producto = A.producto
AND (
B.fecha_mov < A.fecha_mov
OR
(B.fecha_mov = A.fecha_mov AND B.sk <= A.sk)
)
) AS acumulado
FROM
@T AS A
ORDER BY
A.producto,
A.fecha_mov,
A.sk;
GO

/*

producto fecha_mov tipo_mov ingreso salida acumulado


p001 2012-01-01 08:30:00.000 I 200 0 200
p001 2012-01-01 08:35:00.000 E 0 50 150
p001 2012-01-01 08:40:00.000 E 0 70 80

*/
 

AMB
https://social.msdn.microsoft.com/Forums/es-ES/0b09fbbd-7542-4004-b888-4808cb28d5fd/columna-acumulada-en-sql-server-2008?forum=sqlse… 3/4
26/6/2019 Columna Acumulada en SQL Server 2008
AMB
Some guidelines for posting questions...

Marcado como respuesta Eduardo Portescheller Moderator miércoles, 11 de enero de 2012 12:14

lunes, 9 de enero de 2012 14:21

Responder | Citar
Hunchback Bank of America Merchant... (MCC, MVP) 77,015 Puntos

Gracias por la respuesta, voy a probarlo.

Saludos.

0
Inicie miércoles, 11 de enero de 2012 15:04
sesión
para Responder | Citar
votar ChrisPasache 30 Puntos

Centros de desarrollo Recursos de aprendizaje Comunidad Soporte técnico


Microsoft Virtual Academy Foros Autoasistencia
Windows
Channel 9 Blogs

Office MSDN Magazine Codeplex

Visual Studio
Programas
Microsoft Azure BizSpark (para empresas nuevas)
Microsoft Imagine (for students)
Más... Microsoft en la Educación

España (Español) Boletín Privacidad y cookies Términos de uso Marcas comerciales © 2019 Microsoft

https://social.msdn.microsoft.com/Forums/es-ES/0b09fbbd-7542-4004-b888-4808cb28d5fd/columna-acumulada-en-sql-server-2008?forum=sqlse… 4/4

También podría gustarte