困惑: MySQL 用户变量的代码执行顺序

2019-11-05 14:32:20 +08:00
 gettext
select *, 
    CASE 
    	when @fontage = sc.score then @rank
    	when @fontage := sc.score then @rank := @rank + 1 
    END as rank
	FROM (select @fontage:=null,@rank:=0) init, 
		 course, teacher, sc
    where 
        (course.CId=sc.CId
        and course.TId=teacher.TId
        and teacher.Tname = '李四'
        )
	ORDER BY 
		sc.score DESC

https://zhuanlan.zhihu.com/p/32137597

第 34 题,成绩有重复的情况下,查询选修 "李四" 老师所授课程的学生中,成绩最高的学生信息及其成绩

老师就改成“李四”好了

我希望先对 sc.score 降序排序后再执行 CASE END 语句,

但实际运行怎么 ORDER BY sc.score DESC 会是最后执行的?

这不对啊。。。

4701 次点击
所在节点    MySQL
7 条回复
oraZhang
2019-11-05 15:45:51 +08:00
为什么不直接 join 来排序?我觉得那是最直观的吧,你这个变量和 select 多表弄的有点复杂了
oraZhang
2019-11-05 15:47:51 +08:00
@oraZhang 尤其是你要最高的,不是前几名,这样不需要变量来实现排序吧
oraZhang
2019-11-05 15:49:48 +08:00
再回复一下,你 SELECT 里面的数据都是结果条出来之后的运算,所以不太可能你要去先去 SELECT 后 ORDER,如果有这个需求,那么可以子查询包裹下
gettext
2019-11-05 15:50:24 +08:00
@oraZhang #1 我自己没有用多表,上面列出来的是知乎网友的解法,这是不对的。但我就是不理解这种多表情况下 ORDER BY sc.score DESC 会是最后执行的?
gettext
2019-11-05 15:52:12 +08:00
@oraZhang #3

```
select t1.SId,t1.score,
CASE
when @fontage = t1.score then @rank
when @fontage := t1.score then @rank := @rank + 1
END as rank
FROM (select @fontage:=null,@rank:=0) init,
(select sc.SId, sc.Score from course, teacher, sc
where course.CId=sc.CId
and course.TId=teacher.TId
and teacher.Tname = '李四'
ORDER BY
sc.score DESC
) as t1
```

用子查询包裹后就对了,我就是疑惑这个执行顺序
oraZhang
2019-11-05 16:27:11 +08:00
@gettext 就是我上一条说的,SELECT 的语句是在查询最末执行的,比如你没办法用 SELECT 中生成的变量做 WHERE 条件一样, 如 select a as b from t where b > 0;
hooopo
2019-11-05 18:28:25 +08:00
用 window function 咯

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/616487

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX