mySQL基础

it2025-08-16  11

 

SQL执行顺序

(8) SELECT (9)DISTINCT<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> (11) LIMIT <limit_number>

(1) FROM:对FROM子句中的左表<left_table>和右表<right_table>执行笛卡儿积,产生虚拟表VT1; (2) ON: 对虚拟表VT1进行ON筛选,只有那些符合<join_condition>的行才被插入虚拟表VT2; (3) JOIN: 如果指定了OUTER JOIN(如LEFT OUTER JOIN、RIGHT OUTER JOIN),那么保留表中未匹配的行作为外部行添加到虚拟表VT2,产生虚拟表VT3。如果FROM子句包含两个以上的表,则对上一个连接生成的结果表VT3和下一个表重复执行步骤1~步骤3,直到处理完所有的表; (4) WHERE: 对虚拟表VT3应用WHERE过滤条件,只有符合<where_condition>的记录才会被插入虚拟表VT4; (5) GROUP BY: 根据GROUP BY子句中的列,对VT4中的记录进行分组操作,产生VT5;如果应用了group by,那么后面的所有步骤都只能得到的vt5的列或者是聚合函数(count、sum、avg等)。原因在于最终的结果集中只为每个组包含一行。这一点请牢记。 (6) CUBE|ROllUP: 对VT5进行CUBE或ROLLUP操作,产生表VT6; (7) HAVING: 对虚拟表VT6应用HAVING过滤器,只有符合<having_condition>的记录才会被插入到VT7; (8) SELECT: 第二次执行SELECT操作,选择指定的列,插入到虚拟表VT8中; (9) DISTINCT: 去除重复,产生虚拟表VT9; (10) ORDER BY: 将虚拟表VT9中的记录按照<order_by_list>进行排序操作,产生虚拟表VT10; (11) LIMIT: 取出指定街行的记录,产生虚拟表VT11,并返回给查询用户 

Group by和order by执行顺序

下面来分析一样原因:  mysql 写sql的顺序:  select -> from-> where->group by->having->order by.  但mysql的解析器执行顺序: from-> where->group by->having->select->order by.  所以,从执行的流程来看,是先group by 然后在 order by. order by拿到的结果里已经是group by以后的结果.

因此,order by的字段必须是group by 里面已经存在的字段.

 

变量定义

在查询中混合使用过程化和关系化逻辑的时候,自定义变量可能会非常有用。单纯的关系查询将所有的东西都当成无序的数据集合,并且一次性操作它们。 用户自定义变量是一个用来存储内容的临时容器,在连接MySQL的整个过程中都存在。可以使用SET和SELECT来定义他们(在某些情况下,也可以使用=来赋值,不过为了避免歧义,建议始终使用:=):SET @one := 1;SET @min_actor := (SELECT MIN(actor_id) FROM actor);SET @last_week := CURRENT_DATE-INTERVAL 1 WEEK; 然后可以在任何使用表达式的地方使用这些自定义变量:select ... where col <= @last_week;

自定义变量的一个重要的特性是可在给一个赋值的同时使用这个变量。换句话说,用户自定义变量具有“左值特性”,如下: mysql> SET @rownum := 0; mysql> SELECT actor_id, @rownum := @rownum + 1 AS rownum FROM actor LIMIT 3;

 

IF表达式

IF(expr1,expr2,expr3) 如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3。IF() 的返回值为数字值或字符串值,具体情况视其所在语境而定。 例如: -select *,if(sva=1,“男”,“女”) as ssva from taname where sva != “”

IFNULL(expr1,expr2) 假如expr1 不为 NULL,则 IFNULL() 的返回值为 expr1; 否则其返回值为 expr2。IFNULL()的返回值是数字或是字符串,具体情况取决于其所使用的语境。

 

Exists 和 In 的区别,怎么选择?

https://blog.csdn.net/qq_27409289/article/details/85963089

 

Group by

GROUP BY语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表。

select子句中的列名必须为分组列或列函数,列函数对于group by子句定义的每个组返回一个结果。

Group by 和having 详解:https://blog.csdn.net/bingogirl/article/details/52559302

 

Count()

https://blog.csdn.net/qq_31135027/article/details/79858184

 

有慢查询优化经验的同学会清楚,在实际生产中,面对千万上亿级别的数据,连接的效率往往最高,因为用到索引的概率较高。

 

Delete

leecode 196 

https://leetcode-cn.com/problems/delete-duplicate-emails/solution/dui-guan-fang-ti-jie-zhong-delete-he-de-jie-shi-by/

在DELETE官方文档中,给出了这一用法,比如下面这个DELETE语句👇

DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;

这种DELETE方式很陌生,竟然和SELETE的写法类似。它涉及到t1和t2两张表,DELETE t1表示要删除t1的一些记录,具体删哪些,就看WHERE条件,满足就删;

这里删的是t1表中,跟t2匹配不上的那些记录。

 

LIMIT OFFSET

LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #

select * from tableName limit i,n # tableName:表名 # i:为查询结果的索引值(默认从0开始),当i=0时可省略i # n:为查询结果返回的数量 # i与n之间使用英文逗号","隔开 # limit n 等同于 limit 0,n #输出第二个值 limit 1 offset 1

 栗子

# 查询10条数据,索引从0到9,第1条记录到第10条记录 select * from t_user limit 10; select * from t_user limit 0,10; # 查询8条数据,索引从5到12,第6条记录到第13条记录 select * from t_user limit 5,8;

排名窗口函数

专用窗口函数rank, dense_rank, row_number有什么区别呢?

 https://leetcode-cn.com/problems/rank-scores/solution/tu-jie-sqlmian-shi-ti-jing-dian-pai-ming-wen-ti-by/

 

AVG()

求平均值函数的特殊用法 加判断条件(bool型),计算所占比率

https://leetcode-cn.com/problems/trips-and-users/solution/avgchu-ping-jun-zhi-ji-suan-zhi-wai-de-xin-yong-fa/

 

求奇数偶数

id%2 <>0

mod(c,2)=1 来确定奇数 id

 

数据处理函数

 

Trim()

Trim()函数 :去除字符串左右两边的空格 LTrim()函数 :去除字符串左边的空格 RTrim()函数 :去除字符串右边的空格

 

CASE

判断选择函数  leecode 626 https://leetcode-cn.com/problems/exchange-seats/

SELECT (CASE WHEN mod(id,2)=1 AND id != counts THEN id+1 WHEN mod(id,2)=1 AND id = counts THEN id ELSE id-1 END) as id, student FROM seat, ( SELECT count(*) as counts FROM seat )as s_count ORDER BY id UPDATE salary SET sex= ( CASE WHEN sex='f' THEN 'm' ELSE 'f' END ); UPDATE salary SET sex= ( CASE sex WHEN 'f' THEN 'm' ELSE 'f' END );

索引

索引就一种特殊的查询表,数据库的搜索引擎可以利用它加速对数据的检索。它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。索引可以是唯一的,创建索引允许指定单个列或者是多个列。缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。 

视图

https://blog.csdn.net/xyw591238/article/details/

 

 

 

最新回复(0)