gpt4 book ai didi

mysql - 用户变量从上一行中选择值在 MySQL 5.5 中很好,但在 5.6 中它似乎以不同的顺序运行查询的 SELECT 部分

转载 作者:行者123 更新时间:2023-11-29 02:20:20 25 4
gpt4 key购买 nike

我有一个相当不寻常的问题,它是在从本地环境移动到暂存服务器时出现的。 MySQL 版本不同,但我找不到发生此问题的任何原因。

我使用的代码是:

DECLARE _first_event_time datetime;

SELECT event_time INTO _first_event_time
FROM session_events
WHERE session_id = _session_id
ORDER BY event_id ASC LIMIT 0,1;

-- Select Data

SELECT event_id,
event_time,
timediff(event_time, _first_event_time) AS event_time_from_start,
(@previous := unix_timestamp(event_time) - @previous) AS event_duration,
(@previous := unix_timestamp(event_time)) AS previous_event_timestamp
FROM session_events e,

(SELECT @previous:=0) c
ORDER BY event_id ASC LIMIT 0, 400;

我期望的是以下结果,这是我在运行 MAMP 的 DEV 版本上运行 5.5 时得到的结果:

+----------+------------------+-----------------------+----------------+--------------------------+
| event_id | event_time | event_time_from_start | event_duration | previous_event_timestamp |
+----------+------------------+-----------------------+----------------+--------------------------+
| 5074 | 24/09/2015 20:35 | 00:00:00 | 1443123315 | 1443123315 |
| 5075 | 24/09/2015 20:35 | 00:00:02 | 2 | 1443123317 |
| 5076 | 24/09/2015 20:35 | 00:00:03 | 1 | 1443123318 |
| 5077 | 24/09/2015 20:35 | 00:00:03 | 0 | 1443123318 |
| 5078 | 24/09/2015 20:35 | 00:00:04 | 1 | 1443123319 |
| 5079 | 24/09/2015 20:35 | 00:00:05 | 1 | 1443123320 |
| 5080 | 24/09/2015 20:35 | 00:00:06 | 1 | 1443123321 |
| 5081 | 24/09/2015 20:35 | 00:00:06 | 0 | 1443123321 |
| 5082 | 24/09/2015 20:35 | 00:00:07 | 1 | 1443123322 |
| 5083 | 24/09/2015 20:35 | 00:00:08 | 1 | 1443123323 |
| 5084 | 24/09/2015 20:35 | 00:00:09 | 1 | 1443123324 |
| 5085 | 24/09/2015 20:35 | 00:00:10 | 1 | 1443123325 |
+----------+------------------+-----------------------+----------------+--------------------------+

但是数据是这样出来的(请注意数据值不同,因为我在两台服务器上创建了相同的值但是你可以看到数据在哪里被偏移,存储过程中的代码是相同的在两台服务器上):

+----------+------------------+-----------------------+----------------+--------------------------+
| event_id | event_time | event_time_from_start | event_duration | previous_event_timestamp |
+----------+------------------+-----------------------+----------------+--------------------------+
| 5307 | 24/09/2015 20:32 | 00:00:00 | -17 | 1443123174 |
| 5308 | 24/09/2015 20:33 | 00:00:07 | 1443123181 | 1443123181 |
| 5309 | 24/09/2015 20:33 | 00:00:08 | -7 | 1443123182 |
| 5310 | 24/09/2015 20:33 | 00:00:09 | 2 | 1443123183 |
| 5311 | 24/09/2015 20:33 | 00:00:11 | 3 | 1443123185 |
| 5312 | 24/09/2015 20:33 | 00:00:12 | 3 | 1443123186 |
| 5313 | 24/09/2015 20:33 | 00:00:13 | 2 | 1443123187 |
| 5314 | 24/09/2015 20:33 | 00:00:14 | 2 | 1443123188 |
| 5315 | 24/09/2015 20:33 | 00:00:15 | 2 | 1443123189 |
| 5316 | 24/09/2015 20:33 | 00:00:15 | 1 | 1443123189 |
| 5317 | 24/09/2015 20:33 | 00:00:17 | 2 | 1443123191 |
| 5318 | 24/09/2015 20:33 | 00:00:18 | 18 | 1443123192 |
+----------+------------------+-----------------------+----------------+--------------------------+

时区应该没有什么区别,因为这是从数据和存储过程运行的。我还尝试使用以下方法从时间戳更改为仅使用 datediff:

, ( TIME_TO_SEC(TIMEDIFF(event_time, @previous))) AS event_duration
, ( @previous := event_time ) AS previous_event_timestamp

进一步研究一下,问题似乎出在 ORDER BY 子句的某个地方,当在此服务器上初始运行时填充 @previous 字段时,它似乎以未排序的顺序选择结果,就好像我删除了 ORDER BY 子句,并将 @previous 设置为 event_time,然后该顺序就是导致问题的顺序。

如果我只运行一个不带@previous 和 ORDER BY 子句的 select 语句,5.6 服务器返回的数据集似乎与第二个示例中显示的不寻常顺序匹配,其中 @previous 似乎在选择随机值。

我只能认为 SELECT 语句中运行数据并设置 @previous 值的部分首先运行,然后当它返回数据时运行 ORDER BY,这就是问题的来源。

查看 MySQL 手册,我没有发现任何介于 5.5 和 5.6 之间的东西(至少不是我能够归因于发生这种情况的原因)。我想有一种方法可以让它发挥作用。

任何建议将不胜感激,因为我无法弄清楚为什么它按照 ORDER BY 子句之前的顺序进行选举。

最佳答案

MySQL 明确警告不要在同一个select 的不同表达式中使用变量和分配它们。我建议您使用子查询来执行此操作:

SELECT t.*,
(unix_timestamp(event_time) - previous_event_timestamp) as event_duration
FROM (SELECT event_id, event_time,
timediff(event_time, _first_event_time) AS event_time_from_start,
if((@pp := @p) = null, null, -- never happens
if(@p := unix_timestamp(event_time), @pp, @pp)
) AS previous_event_timestamp
FROM session_events e CROSS JOIN
(SELECT @p := 0, @pp := 0) c
ORDER BY event_id ASC
LIMIT 0, 400
) t;

if 逻辑只是将赋值放在同一语句中的一种方式。第一个将 @pp 指定为当前的先前值(在 @p 中)。第二次重新赋值@p,然后返回@pp

然后外部查询对该值进行计算。

documentation说:

As a general rule, other than in SET statements, you should never assign a value to a user variable and read the value within the same statement.

最好避免文档明确警告不要使用的“功能”。

关于mysql - 用户变量从上一行中选择值在 MySQL 5.5 中很好,但在 5.6 中它似乎以不同的顺序运行查询的 SELECT 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32973350/

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