按日期重新排序/更新 SQL 行

发布于 2024-10-17 13:46:22 字数 218 浏览 3 评论 0原文

是否可以对sql表行重新排序?

我有大约 8000 行,它们有点混乱,因为日期与 id 相比是乱序的,我知道您可以通过删除并重新添加 id (INT auto imp) 来重置顺序,但我想按日期重新排序。

我知道我可以简单地从脚本中“按日期排序”,但我宁愿“按 ID 排序”并拥有一个干净的数据库...

我猜它是一个更新...查询,并已在高处和低处搜索了一个答案但尚未找到。

Is it possible to reorder sql table rows?

I have about 8000 rows and they are kinda in a mess as dates are out of order compared to id, I know you can reset order by deleting and re-adding id (INT auto imp) but I want to re-order by date.

I know I could simply 'ORDER BY date' from the script but I would rather 'ORDER BY id' and have a nice clean DB ...

I'm guessing its an UPDATE ... query and have searched high and low for an answer but have yet to find it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

安静 2024-10-24 13:46:23

id 是用来做什么的?更改 ID 似乎没有问题,但如果它在其他地方引用,那就会出现问题。如果它没有在其他地方引用,那么您可能需要重新考虑您的数据库设计,因为该列可能会消失。

如果您仍然想这样做,您可以创建一个带有标识列的新表并插入不带 id 列的行数据,删除旧表并使用旧表的名称重命名新表。

What is the id used for? You seem to not have a problem with changing the ID, but if it referenced elsewhere that will be a problem. If it isn't referenced elsewhere then you might want to rethink your database design as the column can probably go away.

If you still want to do this, could you create a new table with an identity column and insert the row data without the id column, drop the old table and rename the new table using the old table's name.

空袭的梦i 2024-10-24 13:46:22

我不同意你的目标,但我认为你可以编写一个过程,这样:

  • 选择按日期排序的所有行,将它们保存在记录集中(使用游标)
  • 从表中删除所有行
  • 循环添加每一行,利用自动增量 id

I disagree with your goal, but I think you could write a procedure such that:

  • selects all rows ordered by date, saving them in a recordset (using cursor)
  • removes all rows from the table
  • adds cyclically each row, exploiting an auto-incremental id
灼疼热情 2024-10-24 13:46:22

我不太同意这个目标,但是。

在 SQL Server 2005+ 中,您可以使用它。一次性完成此操作可以保持表约束、默认值等完好无损,同时仍然遵守其他表的所有外键挂钩。

create table badlyordered( id int identity, date datetime, otherdata varchar(100))
insert badlyordered(date) select getdate()+4
insert badlyordered(date) select getdate()+2
insert badlyordered(date) select getdate()+3
insert badlyordered(date) select getdate()
insert badlyordered(date) select getdate()+10
insert badlyordered(date) select getdate()-10
update badlyordered set otherdata = date

select * from badlyordered order by id

id          date                    otherdata
----------- ----------------------- ---------------------
7           2011-02-21 18:51:55.087 Feb 21 2011  6:51PM
8           2011-02-19 18:51:55.087 Feb 19 2011  6:51PM
9           2011-02-20 18:51:55.087 Feb 20 2011  6:51PM
10          2011-02-17 18:51:55.087 Feb 17 2011  6:51PM
11          2011-02-27 18:51:55.087 Feb 27 2011  6:51PM
12          2011-02-07 18:51:55.087 Feb  7 2011  6:51PM

;with tmp as (
select *,
table_seq = row_number() over (order by id),
nice_seq = row_number() over (order by date, id)
from badlyordered
)
update t1
set date = t2.date
   ,otherdata = t2.otherdata
   -- and any other columns in the table
from tmp t1
inner join tmp t2 on t1.table_seq=t2.nice_seq

select * from badlyordered order by id

id          date                    otherdata
----------- ----------------------- ---------------------
7           2011-02-07 18:51:55.087 Feb  7 2011  6:51PM
8           2011-02-17 18:51:55.087 Feb 17 2011  6:51PM
9           2011-02-19 18:51:55.087 Feb 19 2011  6:51PM
10          2011-02-20 18:51:55.087 Feb 20 2011  6:51PM
11          2011-02-21 18:51:55.087 Feb 21 2011  6:51PM
12          2011-02-27 18:51:55.087 Feb 27 2011  6:51PM

但我知道你正在使用MySQL。您可以通过使用变量在 MySQL 中对行编号两次,然后使用行号执行更新来执行相同的操作。

这会生成与 SQL Server 中的 CTE 相同的数据。

select ..(rownumber variable by date).. from
(
select ..(rownumber variable by id).. from tbl order by id
) n

然后,您需要其中 2 个(!)

select n.id, o.id
from
(

select ..(rownumber variable by date).. from
(
select ..(rownumber variable by id).. from tbl order by id
) n

inner join

select ..(rownumber variable by date).. from
(
select ..(rownumber variable by id).. from tbl order by id
) n

on ....
) o

来生成从原始到目标的更新 id 的映射。最后,您需要使用 UPDATE FROM JOIN MySQL 技术将表连接到这组 ID 来执行更新。

I don't really agree with the goal, but.

In SQL Server 2005+, you can use this. Doing it in one go keeps table constraints, defaults etc intact while still obeying all foreign key hooks from other tables.

create table badlyordered( id int identity, date datetime, otherdata varchar(100))
insert badlyordered(date) select getdate()+4
insert badlyordered(date) select getdate()+2
insert badlyordered(date) select getdate()+3
insert badlyordered(date) select getdate()
insert badlyordered(date) select getdate()+10
insert badlyordered(date) select getdate()-10
update badlyordered set otherdata = date

select * from badlyordered order by id

id          date                    otherdata
----------- ----------------------- ---------------------
7           2011-02-21 18:51:55.087 Feb 21 2011  6:51PM
8           2011-02-19 18:51:55.087 Feb 19 2011  6:51PM
9           2011-02-20 18:51:55.087 Feb 20 2011  6:51PM
10          2011-02-17 18:51:55.087 Feb 17 2011  6:51PM
11          2011-02-27 18:51:55.087 Feb 27 2011  6:51PM
12          2011-02-07 18:51:55.087 Feb  7 2011  6:51PM

;with tmp as (
select *,
table_seq = row_number() over (order by id),
nice_seq = row_number() over (order by date, id)
from badlyordered
)
update t1
set date = t2.date
   ,otherdata = t2.otherdata
   -- and any other columns in the table
from tmp t1
inner join tmp t2 on t1.table_seq=t2.nice_seq

select * from badlyordered order by id

id          date                    otherdata
----------- ----------------------- ---------------------
7           2011-02-07 18:51:55.087 Feb  7 2011  6:51PM
8           2011-02-17 18:51:55.087 Feb 17 2011  6:51PM
9           2011-02-19 18:51:55.087 Feb 19 2011  6:51PM
10          2011-02-20 18:51:55.087 Feb 20 2011  6:51PM
11          2011-02-21 18:51:55.087 Feb 21 2011  6:51PM
12          2011-02-27 18:51:55.087 Feb 27 2011  6:51PM

But I know you're using MySQL. You can do the same by row-numbering twice in MySQL using variables, then using the row numbers to perform the update.

This produces the same data as the CTE in SQL Server.

select ..(rownumber variable by date).. from
(
select ..(rownumber variable by id).. from tbl order by id
) n

You then need 2(!) of them

select n.id, o.id
from
(

select ..(rownumber variable by date).. from
(
select ..(rownumber variable by id).. from tbl order by id
) n

inner join

select ..(rownumber variable by date).. from
(
select ..(rownumber variable by id).. from tbl order by id
) n

on ....
) o

To produce the map of update ids from original to target. The finally, you need to use an UPDATE FROM JOIN MySQL technique to join the table to this set of IDs to perform the update.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文