【问题标题】:After doing CTE Select Order By and then Update, Update results are not ordered the same (TSQL)执行 CTE 选择 Order By 然后更新后,更新结果的顺序不同(TSQL)
【发布时间】:2016-11-03 18:07:32
【问题描述】:

代码大致是这样的:

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

注意:实际数据有相同的due_date。

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

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

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

【问题讨论】:

  • 我很难找出你真正想用这个实现的目标,但我怀疑数据的顺序是不同的,但它更多地取决于你的选择与输出子句,因为你的输出没有排序。
  • 沿着Microsoft,顺序不保证OUTPUT子句,所以你必须用新的SELECT TOP 4 id, due_date ...替换这个OUTPUT
  • @AllanS.Hansen 抱歉,如果我的问题不清楚。我试图在 cte 选择期间和更新后实现相同的顺序。我假设更新后顺序不会改变。
  • @Polux2 谢谢!我不知道这些信息,我只是假设顺序与 cte 相同。

标签: tsql sql-update common-table-expression sql-order-by


【解决方案1】:

在 MSDN https://msdn.microsoft.com/pl-pl/library/ms177564(v=sql.110).aspx 你可以读到

无法保证应用更改的顺序 到表和行插入的顺序 输出表或表变量会对应。

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

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;

【讨论】:

  • 谢谢!我不知道更新后的订单没有保证。我想这(一批)是我保持订单完整的唯一选择。
猜你喜欢
  • 2021-01-04
  • 2013-10-15
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 2014-08-26
  • 2014-09-01
  • 2016-01-18
  • 1970-01-01
相关资源
最近更新 更多