MySQL CASE 语句在 Workbench 和 Angular 中返回不同的结果
Posted
技术标签:
【中文标题】MySQL CASE 语句在 Workbench 和 Angular 中返回不同的结果【英文标题】:MySQL CASE Statement Returns Different Result in Workbench and Angular 【发布时间】:2021-02-09 21:14:06 【问题描述】:我想从我的 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 值的每一行都会增加 course_number 的值。
然而,在 PHP 中,lesson_number 的值始终为 1(因此每次都必须命中 WHEN @row_number IS NULL)。
语句是相同的,复制和粘贴,并在同一台服务器上运行。一个是从远程连接到服务器的 MySQL Workbench 调用的,另一个是从服务器上用 PHP 编写的 API 调用的。
【问题讨论】:
你运行的是哪个版本的 MySQL? 请向我们展示整个查询,而不仅仅是其中的一部分。 这可能是由于变量范围的问题 -@row_number
是 会话变量,当从 PHP 运行时它的行为可能与您预期的不同跨度>
【参考方案1】:
用户变量在 MySQL 中很棘手 - 现在正式计划在未来版本中弃用它们。
如果您运行的是 MySL 8.0(或者您可以升级到该版本),只需使用窗口函数:dense_rank()
完全符合您的要求。
select
dense_rank() over(order by scrm_lessons_id_lesson) lesson_number,
scrm_lessons_id_lesson lesson_id
from mytable
【讨论】:
非常感谢!那太完美了。【参考方案2】:MySQL explicitly warns agains assigning variables and using them in the same expression:
对于其他语句,例如 SELECT,您可能会得到您期望的结果,但这不能保证。在下面的语句中,你可能会认为 MySQL 会先评估 @a,然后再进行赋值:
SELECT @a, @a:=@a+1, ...;
但是,涉及用户变量的表达式的计算顺序是未定义的。
您在不同的表达式中分配和使用变量,因此无法保证表达式的计算顺序。甚至它们在同一个查询中以相同的顺序被评估。
令人高兴的是,现在不推荐在 SELECT
语句中设置变量。在大多数情况下,您可以将逻辑替换为窗口函数。
编辑:
您的代码似乎描述了该功能:
row_number() over (partition by scrm_lessons_id_lesson order by ?) as lesson_number
?
是因为我不知道排序。它将基于您现有查询中其他地方使用的order by
子句。
【讨论】:
感谢您解释为什么它不能按预期工作。我不知道要使用哪个窗口功能。它们中的任何一个似乎都不符合我的目的。你可以说得更详细点吗?还是我试图用 SQL 做不到,我应该在 API 或客户端的代码中做吗?以上是关于MySQL CASE 语句在 Workbench 和 Angular 中返回不同的结果的主要内容,如果未能解决你的问题,请参考以下文章
mysql之workbench如何只导出(insert语句)数据