drop table salesCREATE TABLE Sales (DayCount smallint, channel varchar(50), Sales money)CREATE CLUSTERED INDEX ndx_DayCount ON Sales(DayCount)goSET NOCOUNT ONDECLARE @DayCount smallint, @Sales money, @channel varchar(50)SET @DayCount = 0SET @Sales = 10set @channel = 'a'WHILE @DayCount < 10000BEGIN INSERT Sales VALUES (@DayCount,@channel, @Sales) SET @DayCount = @DayCount + 1 SET @Sales = @Sales + 15 set @channel = case when right(cast(@daycount as varchar), 1) = 0 then 'a' when right(cast(@daycount as varchar), 1) = 1 then 'b' when right(cast(@daycount as varchar), 1) = 2 then 'c' when right(cast(@daycount as varchar), 1) = 3 then 'd' when right(cast(@daycount as varchar), 1) = 4 then 'e' when right(cast(@daycount as varchar), 1) = 5 then 'f' when right(cast(@daycount as varchar), 1) = 6 then 'g' when right(cast(@daycount as varchar), 1) = 7 then 'h' when right(cast(@daycount as varchar), 1) = 8 then 'i' when right(cast(@daycount as varchar), 1) = 9 then 'j' endEND
--===== Conditionaly drop the test table IF OBJECT_ID('TempDB..#Sales','U') IS NOT NULL DROP TABLE #Sales--===== Populate the table with a million rows of data similar to yours. -- This ISNULL is to make the resulting DayCount column NOT NULL so -- we can put a primary key on it later. SELECT TOP 1000000 ISNULL(CAST(ROW_NUMBER() OVER (ORDER BY sc1.ID) - 1 AS INT),0) AS DayCount, CAST(ROW_NUMBER() OVER (ORDER BY sc1.ID) *15 AS MONEY) AS Sales, CHAR(CAST(ROW_NUMBER() OVER (ORDER BY sc1.ID) - 1 AS INT)%10+ASCII('a')) AS Channel INTO dbo.#Sales FROM Master.sys.SysColumns sc1 CROSS JOIN Master.sys.SysColumns sc2--===== Add the primary key -- I don't name these on temp tables because they must be unique. ALTER TABLE dbo.#Sales ADD PRIMARY KEY CLUSTERED (DayCount)
CREATE TABLE #WACTran( [TranOrder] INT PRIMARY KEY CLUSTERED, [TranType] VARCHAR(3) NULL, [Qty] INT NULL, [UnitCost] DECIMAL(14, 4) NULL, [ExtendedCost] DECIMAL(14, 4) NULL, [QtyOnHand] INT) INSERT INTO [#WACTran](TranOrder, TranType, Qty, UnitCost, ExtendedCost)VALUES (0 ,'BB',100 ,1.5000, 150.0000 ),(1 ,'S',-50 ,0.0000, 0.0000 ),(2 ,'RCT',15 ,0.0000, 0.0000 ),(3 ,'S',-5 ,0.0000, 0.0000 ),(4 ,'VC',15 ,1.6000, 0.0000 ),(5 ,'S',-5 ,0.0000, 0.0000 ),(6 ,'TO',-4 ,0.0000, 0.0000 ),(7 ,'TI',2 ,0.0000, 0.0000 ),(8 ,'VTI',2 ,1.6500, 0.0000 ),(9 ,'RCT',10 ,0.0000, 0.0000 ),(10,'S',-5 ,0.0000, 0.0000 ),(11,'VC',10 ,1.7500, 0.0000 ),(12,'S',-5 ,0.0000, 0.0000 ),(13,'TO',-4 ,0.0000, 0.0000 ),(14,'TI',2 ,0.0000, 0.0000 );--===== Declare some obviously named variablesDECLARE @PrevTranOrder INT, @PrevQtyOnHand INT, @PrevUnitCost DECIMAL(14,4), @PrevExtendedCost DECIMAL(14,4)--===== Do the "quirky" update using a very high speed pseudo-cursor, -- This is very similar to what you would do in a language like "C" except the -- "Read a row/Write a row" is built into the update. UPDATE #WACTran SET @PrevQtyOnHand = QtyOnHand = CASE WHEN TranType = 'BB' THEN Qty WHEN TranType IN ('VTI','VC') THEN @PrevQtyOnHand ELSE @PrevQtyOnHand + Qty END, @PrevUnitCost = UnitCost = CASE WHEN TranType = 'BB' THEN UnitCost WHEN TranType IN ('VTI','VC') THEN (((@PrevQtyOnHand - Qty)*@PrevUnitCost)+(Qty*UnitCost))/@PrevQtyOnHand ELSE @PrevUnitCost END, @PrevExtendedCost = ExtendedCost = CASE WHEN TranType = 'BB' THEN ExtendedCost ELSE @PrevUnitCost*@PrevQtyOnHand END, @PrevTranOrder = TranOrder --Just an "anchor", but gotta have it to guarantee things. FROM [#WACTran] WITH (INDEX(0), TABLOCKX)--===== Display the results SELECT * FROM [#WACTran] ORDER BY TranOrderDROP TABLE #WACTran;