Ayuda con Query de SQL

Hola Chicos… Esto más que una ayuda en SAP sería una ayuda en SQL.

A ver, por alguna extraña razón desconocida para mí, en esta empresa hicieron en algún momento una pantalla para “entrada de inventario” de un almacén de Partes y Componentes, y una pantalla aparte para las “salidas de inventario” de dicho almacén…

No me pregunten porqué no le hicieron un almacén normal en SAP y manejaron sus entradas y salidas normales. No tengo ni la más remota idea y esto está desde el 2005.

Ahora bien. Me están pidiendo un query para conocer la antiguedad de los materiales que se encuentran en ese inventario. Si, ya se que lo mejor será crearles un almacén, hacer las entradas de todos estos materiales ahí, y olvidarme de esto, pero para hacerlo mi jefe quiere saber la antiguedad de los productos.

Bien, tengo este query que me ingresa en una tabla temporal la existencia (una simple resta entre las entradas y las salidas)

SELECT

case when T0.U_ENDescripcion like 'ABRAZADERA%%' then 'ABRAZADERA' 
when T0.U_ENDescripcion like 'ASIENTO%%' then 'ASIENTO' 
when T0.U_ENDescripcion like 'ESPIGA%%' then 'ESPIGA' 
when T0.U_ENDescripcion like 'TAPON%%' then 'TAPON' 
when T0.U_ENDescripcion like 'TERMINAL%%' then 'TERMINAL' 
when T0.U_ENDescripcion like 'TUBO%%' then 'TUBO' 
when T0.U_ENDescripcion like 'TORQ%%' then 'TORQUE' 
when T0.U_ENDescripcion like 'SUBE%%' then 'SUBENSAMBLE' 
when T0.U_ENDescripcion like 'BRAZ%%' then 'BRAZO' 
when T0.U_ENDescripcion like 'BAR%%' then 'BARRA' 
else ' ' end [Tipo],

T0.U_ENArticulo[Artículo],T0.U_ENDescripcion, 

case when SUM(T0.U_ENCantidad) is null then '0' else SUM(T0.U_ENCantidad) end [Entradas], 
case when (t1.Salidas) is null then '0' else (T1.Salidas) end [Salidas],

(case when SUM(T0.U_ENCantidad) is null then '0' else SUM(T0.U_ENCantidad) end -  
case when (t1.Salidas) is null then '0' else (T1.Salidas) end ) [Inventario Final]


into #existencia
from [@ENT01] T0 LEFT OUTER JOIN 
(select U_SAArticulo, case when SUM(U_SACantidad) is null then '0' else SUM(U_SACantidad) end 'Salidas'  from [@SAL01] group by U_SAArticulo) T1 ON T0.U_ENArticulo = T1.U_SAArticulo
group by T0.U_ENArticulo, T0.U_ENDescripcion, t1.Salidas
order by T0.U_ENArticulo

Select * from #existencia where [Inventario Final] > 0 and isnull(artículo,'XXX') <> 'XXX' 

drop table #existencia

Como ven son puras tablas de usuario por eso pongo el código.

Se que lo que debo hacer es tomar de la existencia he ir restando desde la última entrada hacia atrás hasta que el monto de existencia sea 0 y esa será la última entrada del material (o lo más cercano, porque al no trabajar FIFO no puedo asegurarlo).

Es decir…

Existencia = 30
Última entrada 999, cantidad 10, total 20
Total =< 0 fin sino repetir
entrada - 1 998, cantidad 5, total 15
Total =< 0 fin sino repetir
Entrada - 1 997, cantidad 10, total 5
Total =< 0 fin sino repetir
entrada - 1 996 , cantidad 10, total -5
Total =< 0 fin sino repetir
última entrada 996, fecha XX/XX/XXXX


Esto tendría que hacerlo para cada artículo.
La cosa es que se como hacerlo en Visual Basic, y se como hacer la lógica con un While pero no me viene a la mente como lo haría ahorita en SQL…

¿Alguien me ayuda a recordar como se podría hacerlo en SQL?

Hago una respuesta porque si edito se vería raro…

Recordé el tema de los cursores en SQL y resolví de la siguiente manera por si alguien algún día tiene un tema parecido:

SELECT

case when T0.U_ENDescripcion like 'ABRAZADERA%%' then 'ABRAZADERA' 
when T0.U_ENDescripcion like 'ASIENTO%%' then 'ASIENTO' 
when T0.U_ENDescripcion like 'ESPIGA%%' then 'ESPIGA' 
when T0.U_ENDescripcion like 'TAPON%%' then 'TAPON' 
when T0.U_ENDescripcion like 'TERMINAL%%' then 'TERMINAL' 
when T0.U_ENDescripcion like 'TUBO%%' then 'TUBO' 
when T0.U_ENDescripcion like 'TORQ%%' then 'TORQUE' 
when T0.U_ENDescripcion like 'SUBE%%' then 'SUBENSAMBLE' 
when T0.U_ENDescripcion like 'BRAZ%%' then 'BRAZO' 
when T0.U_ENDescripcion like 'BAR%%' then 'BARRA' 
else ' ' end [Tipo],

T0.U_ENArticulo[Artículo],T0.U_ENDescripcion, 

case when SUM(T0.U_ENCantidad) is null then '0' else SUM(T0.U_ENCantidad) end [Entradas], 
case when (t1.Salidas) is null then '0' else (T1.Salidas) end [Salidas],

(case when SUM(T0.U_ENCantidad) is null then '0' else SUM(T0.U_ENCantidad) end -  
case when (t1.Salidas) is null then '0' else (T1.Salidas) end ) [Inventario Final]


into #existencia
from [@ENT01] T0 LEFT OUTER JOIN 
(select U_SAArticulo, case when SUM(U_SACantidad) is null then '0' else SUM(U_SACantidad) end 'Salidas'  from [@SAL01] group by U_SAArticulo) T1 ON T0.U_ENArticulo = T1.U_SAArticulo
group by T0.U_ENArticulo, T0.U_ENDescripcion, t1.Salidas
order by T0.U_ENArticulo

--Select * from #existencia where [Inventario Final] > 0 and isnull(artículo,'XXX') <> 'XXX' 


Declare @existencia_final as table (createdate date, docnum integer, Articulo nvarchar(50), Cantidad Integer, descripcion nvarchar(254))

insert into @existencia_final (createdate, docnum, articulo, cantidad, descripcion)
(
Select 
'01/01/1999' 'Createdate',
'0' docnum,
artículo, 
[Inventario Final],
U_ENDescripcion
from #existencia where [Inventario Final] > 0 and isnull(artículo,'XXX') <> 'XXX'
)


declare @Cantidad2 as integer
declare @documento2 as integer
Declare @fecha as date
declare @entrada as integer
declare @articulo1 as nvarchar(50)
declare @cantidad1 as integer
declare @suma as integer
DECLARE Existencia_Cursor CURSOR FOR  
SELECT T0.createdate, T0.docnum, t1.U_ENArticulo, U_ENCantidad
from [@ENT01] T1 inner join [@ENT] T0 on t0.docentry = T1.docentry  
order by T0.Createdate DESC, T0.docnum DESC
OPEN Existencia_Cursor;  
FETCH NEXT FROM Existencia_Cursor INTO @Fecha, @Entrada, @Articulo1, @cantidad1;  
Set @suma = 999999
WHILE @suma > 0
BEGIN    
	set @Cantidad2 = (Select Cantidad from @existencia_final where articulo = @Articulo1) - @cantidad1
	set @cantidad2 = @cantidad2 
	set @documento2 = (Select docnum from  @existencia_final where articulo = @Articulo1)
--	Select *, @cantidad1 'entrada', @cantidad2 'restante', @documento2 'Documento', @articulo1 ' articulo' from @existencia_final where articulo = @Articulo1
	if @documento2 = 0
	 Begin 
	  If @Cantidad2 > 0 
	   begin
		update @existencia_final set
		cantidad = @cantidad2
		from @existencia_final where articulo = @Articulo1
	   end
	  if @Cantidad2 <= 0
	   begin 
	    update @existencia_final set
		cantidad = @cantidad2,
		Createdate = @fecha,
		docnum = @entrada
		from @existencia_final where articulo = @Articulo1
	   end	  
	 end
	set @suma = (select Sum(cantidad) from @existencia_final where cantidad >= 0 )
	FETCH NEXT FROM Existencia_Cursor INTO @Fecha, @Entrada, @Articulo1, @cantidad1;
END
CLOSE  Existencia_Cursor;  
DEALLOCATE  Existencia_Cursor;  

Select articulo, descripcion, docnum 'Entrada antiguedad', createdate 'Fecha antiguedad'
, T1.[Inventario Final] 'existencia actual'
 from @existencia_final T0 inner join #existencia T1 on T0.Articulo = T1.Artículo  
 where [Inventario Final] > 0
 order by t0.createdate, t0.Articulo

drop table #existencia

Aunque son tablas de usuarios, la idea y el orden puede servir por si alguien necesita hacer una búsqueda del mismo estilo.

1 me gusta