我正在努力在合理的时间内更新数据库中的980,000条记录。
我必须在PriceID等于一个组的最大值(按ProductID分组)的行中将NextLp的值设置为'NULL'。
为直观起见,这是我的示例:
+-----------+---------+--------+---------------------+ | ProductID | PriceID | NextLp | Set NextLp to NULL? | +-----------+---------+--------+---------------------+ | APPLE | 1 | - | | +-----------+---------+--------+---------------------+ | APPLE | 2 | - | | +-----------+---------+--------+---------------------+ | APPLE | 3 | - | Yes | +-----------+---------+--------+---------------------+ | PEAR | 1 | - | | +-----------+---------+--------+---------------------+ | PEAR | 2 | - | Yes | +-----------+---------+--------+---------------------+
我尝试了各种方法,但是所有这些方法至少要花15秒来更新100条记录..还有979,100条要走-所以我的方法肯定不可行。
感谢您的帮助。
版本为MS SQL 2016
答案 0 :(得分:4)
也许是这样吗?
DECLARE @tbl TABLE(ProductID VARCHAR(100),PriceID INT,NextLp VARCHAR(100));
INSERT INTO @tbl VALUES
('APPLE',1,'-')
,('APPLE',2,'-')
,('APPLE',3,'-')
,('PEAR ',1,'-')
,('PEAR ',2,'-');
WITH UpdatableCTE AS
(
SELECT *
,ROW_NUMBER() OVER(PARTITION BY ProductID ORDER BY PriceID DESC) AS Nr
FROM @tbl
)
UPDATE UpdatableCTE SET NextLp=NULL
WHERE Nr=1;
SELECT * FROM @tbl;
您可以先使用可更新的CTE将数字放置到行中,然后再更新您要定位的数字。
结果
ProductID PriceID NextLp
APPLE 1 -
APPLE 2 -
APPLE 3 NULL
PEAR 1 -
PEAR 2 NULL
在上面的示例中,将两行设置为NULL
。两行都是其组中的最高价格ID ...
ROW_NUMBER()
是a window function。 OVER()
-clause允许PARTITION BY
在集合内创建组,而ORDER BY
将对组进行排序,在这种情况下,将按PriceID
降序排列。这会将1
绑定到每一行,其中PriceID
在ProductID
组中是最高的。
提示:您可以使用SELECT * FROM UpdatableCTE
代替UPDATE
语句。这将向您显示编号的行,并允许检查编号。