如何使用col2中的下一个非零值更新零?
例如 - 我需要使用值2更新col2中的前3行。同样,我需要在2之后接下来的两个值更新为3(对于RN 5,6)
基本上,在每个尾随零之后,如果存在非零,则应该在上面的尾随零中更新它。
如何使用loops
和procedures
?
答案 0 :(得分:4)
以下是对此的简单查询,您可以使用OUTER APPLY
CREATE TABLE #tmp(rn INT IDENTITY(1,1), col1 VARCHAR(50), col2 INT, col3 DATE)
INSERT INTO #tmp VALUES
('ABC', 0, '2017-01-01'),
('ABC', 0, '2017-01-01'),
('ABC', 0, '2017-01-01'),
('ABC', 2, '2017-01-01'),
('ABC', 0, '2014-02-01'),
('ABC', 0, '2013-02-01'),
('ABC', 3, '2013-01-01'),
('ABC', 0, '2017-01-01'),
('ABC', 0, '2017-01-01'),
('ABC', 0, '2017-01-01'),
('ABC', 0, '2017-01-01'),
('ABC', 7, '2017-01-01')
UPDATE t SET t.col2 = t2.col2
FROM #tmp t
OUTER APPLY(SELECT TOP 1 col2 FROM #tmp WHERE rn >= t.rn AND col2 > 0) t2
输出:
rn col1 col2 col3
1 ABC 2 2017-01-01
2 ABC 2 2017-01-01
3 ABC 2 2017-01-01
4 ABC 2 2017-01-01
5 ABC 3 2014-02-01
6 ABC 3 2013-02-01
7 ABC 3 2013-01-01
8 ABC 7 2017-01-01
9 ABC 7 2017-01-01
10 ABC 7 2017-01-01
11 ABC 7 2017-01-01
12 ABC 7 2017-01-01
答案 1 :(得分:3)
试试这个
DECLARE @T TABLE
(
RN INT IDENTITY(1,1),
COL1 VARCHAR(20),
COL2 INT,
COL3 DATE,
COL2_NEW INT NULL
)
INSERT INTO @T(COL1,COL2,COL3)
VALUES('ABC',0,'1/1/2017'),
('ABC',0,'01/01/2017'),
('ABC',0,'01/01/2017'),
('ABC',2,'01/01/2017'),
('ABC',0,'01/01/2017'),
('ABC',0,'01/01/2017'),
('ABC',3,'01/01/2014'),
('ABC',0,'01/01/2017')
;WITH CTE
AS
(
SELECT
SeqNo = ROW_NUMBER() OVER(PARTITION BY T1.RN ORDER BY T1.RN,T2.RN),
T1.RN,
T2RN = T2.RN,
T2.COL2
FROM @T T1
INNER JOIN @T t2
ON T1.COL1 = T2.COL1
AND T1.COL2 = 0
AND T2.COL2 > 0
AND T1.RN < T2.RN
)
UPDATE @T
SET
COL2_NEW = CTE.COL2
FROM CTE
INNER JOIN @T T
ON T.RN = CTE.RN
WHERE CTE.SeqNo = 1
SELECT
*
FROM @T
答案 2 :(得分:2)
假设RN
是我们确定列顺序的列:
UPDATE t
SET col2 = t2.col2
FROM
table t
inner join
table t2
on
t.rn < t2.rn and
t2.col2 != 0
left join
table t_anti
on
t.rn < t_anti.rn and
t_anti.rn < t2.rn and
t_anti.col2 != 0
where
t.col2 = 0 and
t_anti.rn is null
基本上,我们基于找到具有非零值的后一行将表连接到自身。然后,我们执行进一步的连接,尝试为后一行找到“更好”的匹配。只有当该加入失败时(null
子句中的最终where
检查),我们才知道我们已找到t2
中的最佳匹配。
答案 3 :(得分:1)
这是一个展示概念的快速脚本。对于每一行,找到值为非零的下一个RN,然后将该值更新为该RN的值。
CREATE TABLE #tt(RN INT IDENTITY(1,1) PRIMARY KEY, val INT);
INSERT INTO #tt(val)VALUES(0),(0),(0),(2),(0),(0),(3),(0);
SELECT * FROM #tt;
UPDATE
#tt
SET
val=ISNULL((SELECT val FROM #tt AS r WHERE r.RN=mrn.RN),0)
FROM
#tt AS o
CROSS APPLY (
SELECT
RN=MIN(RN)
FROM
#tt AS i
WHERE
i.val<>0 AND i.RN>=o.RN
) AS mrn;
SELECT * FROM #tt;
DROP TABLE #tt;