How can I do this without the cursor:
SET NOCOUNT ON;
DECLARE @VAR_A BIGINT, @VAR_B TINYINT;
DECLARE _CURSOR CURSOR FOR
SELECT A, B FROM MY_TABLE
OPEN _CURSOR
FETCH NEXT FROM _CURSOR
INTO @VAR_A, @VAR_B
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT TOP 2 A, B, C, ROW_NUMBER() OVER (ORDER BY A DESC) AS ROW_NUM
INTO #TMP FROM MY_TABLE_2
WHERE A = @VAR_A AND X = 0 ORDER BY A DESC
IF ((SELECT COUNT(*) FROM #TMP) = 1) BEGIN
UPDATE MY_TABLE
SET Y = (SELECT B FROM #TMP WHERE ROW_NUM = 1)
WHERE A = @VAR_A
END ELSE IF (@VAR_B = 7) BEGIN
UPDATE MY_TABLE
SET Y = (SELECT B FROM #TMP WHERE ROW_NUM = 2),
Z = (SELECT C FROM #TMP WHERE ROW_NUM = 2)
WHERE A = @VAR_A
END ELSE BEGIN
UPDATE MY_TABLE
SET Y = (SELECT B FROM #TMP WHERE ROW_NUM = 2)
WHERE A = @VAR_A
END
DROP TABLE #TMP
FETCH NEXT FROM _CURSOR
INTO @VAR_A, @VAR_B
END
CLOSE _CURSOR;
DEALLOCATE _CURSOR;
I have a PRODUCT table, this table has a status column, the last status of the product. I have another table, the PRODUCT_HISTORY, that have all information changed on product, including the older status. For each product, I need to get the last status and insert it on a new field on product table. Like this:
This should do the trick...
IF OBJECT_ID('tempdb..#Product', 'U') IS NOT NULL
DROP TABLE #Product;
CREATE TABLE #Product (
Id INT NOT NULL PRIMARY KEY CLUSTERED,
[Description] VARCHAR(20) NOT NULL,
[Status] INT NOT NULL,
OlderStatus INT NULL
);
INSERT #Product (Id, [Description], [Status]) VALUES
(1, 'Product A', 5),
(2, 'Product B', 7),
(3, 'Product C', 4),
(4, 'Product D', 3),
(5, 'Product E', 0);
IF OBJECT_ID('tempdb..#ProductHistory', 'U') IS NOT NULL
DROP TABLE #ProductHistory;
CREATE TABLE #ProductHistory (
Id INT NOT NULL PRIMARY KEY CLUSTERED,
[Date] DATE NOT NULL,
Status INT NOT NULL,
ProductId INT NOT NULL
);
INSERT #ProductHistory (Id, [Date], [Status], ProductId) VALUES
(1, '2017-01-01', 0, 1),
(2, '2017-01-02', 1, 1),
(3, '2017-01-03', 5, 1),
(4, '2017-01-04', 0, 2),
(5, '2017-01-05', 1, 2),
(6, '2017-01-06', 5, 2),
(7, '2017-01-07', 7, 2),
(8, '2017-01-08', 0, 3),
(9, '2017-01-09', 4, 3),
(10, '2017-01-10', 0, 4),
(11, '2017-01-11', 3, 4),
(12, '2017-01-12', 0, 5);
--===================================================
-- the actual solution...
WITH
cte_PH AS (
SELECT
ph.Id, ph.Date, ph.Status, ph.ProductId,
RN = ROW_NUMBER() OVER (PARTITION BY ph.ProductId ORDER BY ph.Date DESC)
FROM
#ProductHistory ph
)
UPDATE p SET
p.OlderStatus = ISNULL(ph.Status, 0)
FROM
#Product p
LEFT JOIN cte_PH ph
ON p.id = ph.ProductId
AND ph.RN = 2;
----------------------------------------
SELECT * FROM #Product p;
Results...
Id Description Status OlderStatus
----------- -------------------- ----------- -----------
1 Product A 5 1
2 Product B 7 5
3 Product C 4 0
4 Product D 3 0
5 Product E 0 0