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个徽章,以获取你想要的结果集。