【问题标题】:SQL update order in relation ship based on ID基于ID的关系中的SQL更新顺序
【发布时间】:2022-01-22 08:53:13
【问题描述】:

我想知道如何使用基于 PostsId 的 SQL 为多对多关系更新此表中的顺序。 所以我的桌子现在看起来像:

我正在使用 SQL Server

BlogsId PostsId Order
1 1 1 0
2 2 1 0
3 3 2 0
3 4 2 0
3 5 3 0
3 6 3 0

但我想使用 SQL 将 Order 更新为:

BlogsId PostsId Order
1 1 1 1
2 2 1 2
3 3 2 1
3 4 2 2
3 5 3 1
3 6 3 2

例如:ID 为 3 的博客是 ID 为 2 的帖子中的第一个博客,ID 为 4 的博客是 ID 为 2 的帖子中的第二个博客,依此类推...

我试过了:

DECLARE @myVar int
SET @myVar = 0
UPDATE [dbo].[BlogPost]
SET @myVar = [Order] = @myVar + 1

但后来我得到了这个:

BlogsId PostsId Order
1 1 1 1
2 2 1 2
3 3 2 3
3 4 2 4
3 5 3 5
3 6 3 6

所以,我认为我应该在 WHERE 部分做点什么(也许是 Distinct),但我不知道具体是什么。我可以用 C# 写一些东西来做我想做的事,但我不知道如何用 SQL 写这样的东西。

【问题讨论】:

  • 当有人稍后删除行 (4. 2, 4) 时会发生什么?
  • 根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或键入问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。
  • 当有人从表中删除一行时,我将手动执行相同的查询以重新排序
  • 好的,我会尝试重新组织我的问题

标签: sql sql-server tsql


【解决方案1】:

物理上维护行的顺序或序列很少是一个好主意,并且可能导致数据不一致和其他无法预料的问题。

你最好创建一个 view 来提供额外的 Order 列,你可以使用 row_number()

Create view BlogPosts as
select *,
    Row_Number() over(partition by PostsId order by BlogsId) as [Order]
from blogpost;

如果您真的想更新表中的实际列,您可以使用 CTE

with b as (
    select *,
        Row_Number() over(partition by PostsId order by BlogsId) as seq
    from blogpost
)
update b
set [Order] = seq;

【讨论】:

  • 嗨 Stu,谢谢你的帮助,它就像一个魅力 :) 我知道手动执行脚本是一种不好的做法。我围绕这个编写了我的 c# 代码,因此代码将以正确的方式处理添加、更新和删除(当设置顺序时),所以只有当有人直接在数据库中做错事时,我才需要手动执行这个脚本。而且我认为我会尝试更多地了解 SQL,并且可能会编写一些触发器和过程来放松我的代码。我会考虑你的建议!万分感谢! :)
【解决方案2】:

您可以根据计算的 row_number 进行更新。

update t 
set [Order] = rn
from (
  select BlogsId, PostsId, [Order]
  , rn = row_number() over (partition by PostsId order by BlogsId asc)
  from BlogPost
) t
where ([Order] is null or [Order]!=rn);
select *
from BlogPost
order by BlogsId, PostsId
BlogsId PostsId Order
1 1 1
2 1 2
3 2 1
4 2 2
5 3 1
6 3 2

dbfiddle here

上的演示

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    相关资源
    最近更新 更多