mysql 书学顺序和查询顺序
这里涉及SQL语句的语法顺序和执行顺序了,我们常见的SQL语法顺序如下:
SELECT DISTINCT <Top Num> <select list>
FROM [left_table] <join_type>
JOIN <right_table> ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
WITH <CUBE | RollUP>
HAVING <having_condition>
ORDER BY <order_by_list>
而数据库引擎在执行SQL语句并不是从SELECT开始执行,而是从FROM开始,具体执行顺序如下(关键字前面的数字代表SQL执行的顺序步骤):
(8)SELECT (9)DISTINCT (11)<Top Num> <select list>
(1)FROM [left_table]
(3)<join_type> JOIN <right_table>
(2) ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>
从上面可以看到SELECT在HAVING后才开始执行,这个时候SELECT后面列的别名只对后续的步骤生效,而对SELECT前面的步骤是无效的。所以如果你在WHERE,GROUP BY,或HAVING后面使用列的别名均会报错。
不少地方说的顺序和这个不太一致:主要是select 和 order的关系,谁先谁后的问题

本人亲自实验:先order by 再 select。
SELECT *
FROM (
SELECT *,
IF(@prev_space_id = space_id, @row_number := @row_number + 1, @row_number := 1) as row_number,
@prev_space_id := space_id
FROM badges, (SELECT @prev_space_id := NULL, @row_number := 0) as vars
ORDER BY space_id, created_at DESC
) as t
WHERE row_number <= 4;
以上代码是先按照space_id, created_at分组。然后每组按顺序设置row_number。
详解:
这个查询语句使用了 MySQL 中的变量和子查询来模拟 ROW_NUMBER() 窗口函数的功能。让我们逐步解释它的执行过程:
-
首先,它创建了一个名为
vars的子查询,并定义了两个变量@prev_space_id和@row_number,并将它们都初始化为 0。这个子查询只会执行一次,并在后续查询中使用这两个变量。(SELECT @prev_space_id := NULL, @row_number := 0) as vars ``` -
然后,它从
badges表中选择所有列,并将其与vars子查询进行交叉连接。这个查询会将badges表中的每一行都复制一遍,并将@prev_space_id和@row_number变量的值初始化为 0。lessFROM badges, (SELECT @prev_space_id := NULL, @row_number := 0) as vars ``` -
接下来,它使用
IF函数和变量来为每个space_id分配一个行号row_number。对于每个徽章,如果其space_id等于上一行的space_id,则将@row_number的值加 1,并将该值作为row_number的值;否则,将@row_number重置为 1,并将其作为row_number的值。同时,将当前space_id的值保存到@prev_space_id变量中,以便下一行使用。lessIF(@prev_space_id = space_id, @row_number := @row_number + 1, @row_number := 1) as row_number, @prev_space_id := space_id ``` -
最后,它将所有列和计算出的
row_number值作为结果集返回。这个查询不会过滤或排序结果,只是为每个徽章分配了一个行号。SELECT *, IF(...), ... ```
你可以将这个查询语句作为子查询,然后在外部查询中选择每个 space_id 下行号最小的4个徽章,以获取你想要的结果集。

浙公网安备 33010602011771号