gpt4 book ai didi

mysql - 嵌套 SQL 查询中的排序依据

转载 作者:行者123 更新时间:2023-12-04 10:05:45 25 4
gpt4 key购买 nike

我想就我在 MySQL 中使用“order by”指令时遇到的一个奇怪事实寻求您的帮助

让我们看看下表:

CREATE TABLE `test_nested_order_by` (
`id` int(11) NOT NULL,
`timestamp` int(11) NOT NULL COMMENT 'Timestamp',
`index_continuity_month` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

insert into test_nested_order_by (id,timestamp,index_continuity_month) values (1,1583772141,0) ;
insert into test_nested_order_by (id,timestamp,index_continuity_month) values (1,1583708400,0) ;
insert into test_nested_order_by (id,timestamp,index_continuity_month) values (5,1583708400,0) ;
insert into test_nested_order_by (id,timestamp,index_continuity_month) values (4,1583708400,0) ;
insert into test_nested_order_by (id,timestamp,index_continuity_month) values (5,1583794800,0) ;
insert into test_nested_order_by (id,timestamp,index_continuity_month) values (4,1583794800,0) ;

如您所见,为每一行的“index_continuity_month”列设置了 0 值。

我现在想如下设置这个值:一个唯一的值,它将按照 id 和时间戳列的升序递增。该表将如下所示:
mysql>  select * from test_nested_order_by :

+----+------------+------------------------+
| id | timestamp | index_continuity_month |
+----+------------+------------------------+
| 1 | 1583772141 | 2 |
| 1 | 1583708400 | 1 |
| 5 | 1583708400 | 5 |
| 4 | 1583708400 | 3 |
| 5 | 1583794800 | 6 |
| 4 | 1583794800 | 4 |
+----+------------+------------------------+
6 rows in set (0,00 sec)

或者,如果您更喜欢:
mysql> select * from test_nested_order_by order by id,timestamp ;
+----+------------+------------------------+
| id | timestamp | index_continuity_month |
+----+------------+------------------------+
| 1 | 1583708400 | 1 |
| 1 | 1583772141 | 2 |
| 4 | 1583708400 | 3 |
| 4 | 1583794800 | 4 |
| 5 | 1583708400 | 5 |
| 5 | 1583794800 | 6 |
+----+------------+------------------------+

为此,我使用此查询:
UPDATE  test_nested_order_by t1,
(SELECT
id,
timestamp,
@last_continuity_month := @last_continuity_month +1, @last_continuity_month AS index_continuity_month

FROM test_nested_order_by, (

SELECT @last_continuity_month :=0
)SQLVars
ORDER BY id , timestamp) t2

SET t1.index_continuity_month = t2.index_continuity_month

WHERE t1.id = t2.id
AND t1.timestamp = t2.timestamp;

但是当我看到结果时,它似乎不起作用:
mysql> select * from test_nested_order_by order by id,timestamp ;
+----+------------+------------------------+
| id | timestamp | index_continuity_month |
+----+------------+------------------------+
| 1 | 1583708400 | 2 |
| 1 | 1583772141 | 1 |
| 4 | 1583708400 | 4 |
| 4 | 1583794800 | 6 |
| 5 | 1583708400 | 3 |
| 5 | 1583794800 | 5 |
+----+------------+------------------------+
6 rows in set (0,00 sec)

我怀疑没有考虑“order by”指令(如果我从查询中删除它,结果是完全一样的)。

我们可以注意到 index_continuity_month 的递增不是按照 id 和 timestamp 列的升序进行的,而是按照行插入表中的顺序进行的。

但是,如果我只运行查询的嵌套部分:
SELECT
id,
timestamp,
@last_continuity_month := @last_continuity_month +1, @last_continuity_month AS index_continuity_month

FROM test_nested_order_by, (

SELECT @last_continuity_month :=0
)SQLVars
ORDER BY id , timestamp;

+----+------------+-----------------------------------------------------+------------------------+
| id | timestamp | @last_continuity_month := @last_continuity_month +1 | index_continuity_month |
+----+------------+-----------------------------------------------------+------------------------+
| 1 | 1583708400 | 1 | 1 |
| 1 | 1583772141 | 2 | 2 |
| 4 | 1583708400 | 3 | 3 |
| 4 | 1583794800 | 4 | 4 |
| 5 | 1583708400 | 5 | 5 |
| 5 | 1583794800 | 6 | 6 |
+----+------------+-----------------------------------------------------+------------------------+

结果很好!

有没有人可以解释我的问题是什么?更具体地说,为什么 SQL 查询在嵌套到另一个查询中时没有相同的行为?

非常感谢 !

最佳答案

首先:如果您正在运行 MySQL 8.0,这很容易通过 row_number() 完成。 :

update test_nested_order_by t
inner join (
select
t.*,
row_number() over(order by id, timestamp) rn
from test_nested_order_by t
) t1 on t1.id = t.id and t1.timestamp = t.timestamp
set t.index_continuity_month = t1.rn

在早期版本中,用户变量确实是一个解决方案;但是将它们与 order by 一起使用很棘手。那是因为 order by通常在 select 之后处理子句,因此不能保证将“正确”值分配给每一行。要解决此问题,您需要先在子查询中对表进行排序,然后设置变量:
update test_nested_order_by t
inner join (
select t.*, @rn := @rn + 1 rn
from (select * from test_nested_order_by order by id, timestamp) t
cross join (select @rn := 0) x
) t1 on t1.id = t.id and t1.timestamp = t.timestamp
set t.index_continuity_month = t1.rn

Demo on DB Fiddle - 两者 update查询产生以下结果:
select * from test_nested_order_by order by id, timestamp

身份证 |时间戳 | index_continuity_month
-: | ---------: | ---------------------:
1 | 1583708400 | 1
1 | 1583772141 | 2
4 | 1583708400 | 3
4 | 1583794800 | 4
5 | 1583708400 | 5
5 | 1583794800 | 6

关于mysql - 嵌套 SQL 查询中的排序依据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61600059/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com