MySQL CASE 语句 Returns Workbench 和 Angular 中的不同结果

MySQL CASE Statement Returns Different Result in Workbench and Angular

我想从 PHP API 中获得与从 MySQL Workbench 中调用相同的 SQL 查询时得到的结果相同的结果。 我在 MySQL Workbench 中得到的结果与在使用 CASE 语句时从 PHP API 调用它时得到的结果不同。这是 SQL:

@row_number:=CASE
                            WHEN @row_number IS NULL THEN
                                1
                            WHEN @dateTime = scrm_lessons_id_lesson THEN 
                                @row_number + 0
                            WHEN @dateTime != scrm_lessons_id_lesson THEN 
                                @row_number + 1
                            END AS lesson_number,
                          
                        @dateTime:= scrm_lessons_id_lesson AS 'LessonID'

在 Workbench 中,这给了我想要的结果,即:

lesson_number   LessonID
1   17282
2   17314
2   17314
2   17314
2   17314
2   17314
2   17314
2   17314
2   17314
3   17349
3   17349
3   17349
3   17349
3   17349
3   17349
3   17349
3   17349
4   17386
4   17386
4   17386
4   17386
4   17386
5   17416
5   17416

即,具有新 LessonID 值的每一行都会增加 lesson_number 的值。

然而,在PHP中,lesson_number的值始终为1(所以它必须每次都命中WHEN @row_number IS NULL)。

语句完全相同,复制粘贴,和运行在同一台服务器上。一个是从远程连接到服务器的 MySQL Workbench 调用的,另一个是从服务器上的 API 调用的 PHP.

用户变量在 MySQL 中很棘手 - 现在正式计划在未来的版本中弃用它们。

如果您是 运行 MySL 8.0(或者您可以升级到该版本),只需使用 window 功能:dense_rank() 完全满足您的要求。

select 
    dense_rank() over(order by scrm_lessons_id_lesson) lesson_number, 
    scrm_lessons_id_lesson  lesson_id
from mytable

MySQL explicitly warns agains assigning variables and using them in the same expression:

For other statements, such as SELECT, you might get the results you expect, but this is not guaranteed. In the following statement, you might think that MySQL will evaluate @a first and then do an assignment second:

SELECT @a, @a:=@a+1, ...;

However, the order of evaluation for expressions involving user variables is undefined.

您在不同的表达式中分配和使用变量,因此无法保证表达式的计算顺序。甚至它们在同一查询中以相同的顺序进行评估。

幸运的是,现在不推荐在 SELECT 语句中设置变量。在大多数情况下,您可以用 window 函数替换逻辑。

编辑:

您的代码似乎描述了功能:

row_number() over (partition by scrm_lessons_id_lesson order by ?) as lesson_number

?是因为不知道顺序。它将基于您现有查询中其他地方使用的 order by 子句。