使用 where 和 order by 子句从 1 更新序列号的列
Posted
技术标签:
【中文标题】使用 where 和 order by 子句从 1 更新序列号的列【英文标题】:Update a column with sequence number from 1 with a where and order by clauses 【发布时间】:2019-05-20 06:39:51 【问题描述】:我正在尝试执行以下 SQL 查询来更新名为 seq
的列,其中包含特定 ID 的编号序列,但它会引发错误:
关键字“ORDER”附近的语法不正确。
DECLARE @id INT
SET @id = 0
UPDATE T_TRNHIST
SET @id = seq = @id + 1
WHERE Acc='12344'
OPTION ( MAXDOP 1 )
ORDER BY Recid, trnDate
我哪里出错了?
【问题讨论】:
为什么不用buseROW_NUMBER
代替?
我认为您不能在 UPDATE
语句中使用 ORDER BY
。 ***.com/questions/3439110/…
你能告诉我们,这样的查询背后的目的是什么?
【参考方案1】:
您不能在更新语句中使用order by
,并且在使用古怪的更新时应该非常小心,因为它们非常不可预测。
一个简单、可靠的解决方案是使用带有row_number
的可更新公用表表达式:
WITH CTE AS
(
SELECT seq,
ROW_NUMBER() OVER(ORDER BY Recid, trnDate) As rn
FROM T_TRNHIST
)
UPDATE CTE
SET seq = rn
【讨论】:
【参考方案2】:您可以尝试UPDATE ... FROM ...
语法,它允许使用JOIN
。这是代码 sn-p 以及测试数据:
declare @tbl table (seq int, Acc varchar(10), RecId int, trnDate date);
insert into @tbl values
(null, '12344', 2, '2019-05-05'),
(null, '12344', 1, '2019-05-06'),
(null, '12344', 5, '2019-05-04'),
(null, '12344', 5, '2019-05-03'),
(null, '12355', 1, '2019-05-05');
select * from @tbl
update t1 set t1.seq = t2.rn
from @tbl t1 join (
select row_number() over (order by RecId, trnDate) rn,
trnDate,
RecId,
Acc
from @tbl
where Acc = '12344'
) t2 on t1.trnDate = t2.trnDate and t1.RecId = t2.RecId and t1.Acc = t2.Acc
select * from @tbl
【讨论】:
以上是关于使用 where 和 order by 子句从 1 更新序列号的列的主要内容,如果未能解决你的问题,请参考以下文章
SQL语句中,为啥where子句不能使用列别名,而order by却可以?
在 where 子句和 order by 子句之间的 MySQL 索引
第二章:oracle_sql语句之限制(where子句)和排列数据(order by子句)