执行CTE后,选择Order By然后进行更新,更新结果的顺序不同(TSQL)

执行CTE后,选择Order By然后进行更新,更新结果的顺序不同(TSQL),tsql,sql-update,common-table-expression,sql-order-by,Tsql,Sql Update,Common Table Expression,Sql Order By,代码大致如下: WITH cte AS ( SELECT TOP 4 id, due_date, check FROM table_a a INNER JOIN table_b b ON a.linkid = b.linkid WHERE b.status = 1 AND due_date > GetDate() ORDER BY due_date, id ) UPDATE cte SET check = 1 OUTPUT INSERTED.id, INSERTED.

代码大致如下:

WITH cte AS
(
 SELECT TOP 4 id, due_date, check
 FROM table_a a
 INNER JOIN table_b b ON a.linkid = b.linkid
 WHERE
  b.status = 1
  AND due_date > GetDate()
 ORDER BY due_date, id
)
UPDATE cte
SET check = 1
OUTPUT
 INSERTED.id,
 INSERTED.due_date
注:实际数据具有相同的到期日

当我只在cte内部运行SELECT语句时,我可以得到结果,例如:1、2、3、4。 但是在UPDATE语句之后,更新的结果是:4、1、2、3

为什么会发生这种(订单变更)

如何在同一查询中将结果保留或重新排序回1,2,3,4?

在MSDN中,您可以阅读

无法保证更改的应用顺序 到表以及行插入到表中的顺序 输出表或表变量将对应

这意味着你不能只用一个查询就解决你的问题。但是你仍然可以用一批来做你需要的事情。因为您的输出不能保证顺序,所以您必须将其保存在另一个表中,并在更新后对其进行排序。此代码将返回您的输出值,以便您假定:

declare @outputTable table( id int, due_date date);

with cte as (
    select top 4 id, due_date, check
    from table_a a
    inner join table_b b on a.linkid = b.linkid
    where b.status = 1
    and due_date > GetDate()
    order by due_date, id
)
update cte
set check = 1
output inserted.id, inserted.due_date
into @outputTable;

select *
from @outputTable
order by due_date, id;

我很难弄清楚你到底想用这个实现什么,但我怀疑数据的顺序是不同的,但更多的是取决于你的select和output子句,因为你的输出没有顺序。此外,output子句不能保证顺序,所以你必须用一个新的
select TOP 4 id替换这个输出,截止日期…
@AllanS.Hansen如果我的问题不清楚,很抱歉。我试图在cte选择期间和更新之后实现相同的顺序。我假设更新后订单不会更改。@Polux2谢谢!我不知道这些信息,我只是假设订单与cte相同。谢谢!我不知道更新后的订单中没有保证这一事实。我想这(一批)是我保持订单完整的唯一选择。