Mysql
SQL简介
什么是SQL
- SQL 指结构化查询语言,全称是 Structured Query Language。
- SQL 让您可以访问和处理数据库,包括数据插入、查询、更新和删除。
- SQL 语言采用英语关键词,使其易读易写。
- SQL 提供了丰富的操作数据的功能,从简单的查询到复杂的数据库管理操作。
SQL能做什么
- 面向数据库执行查询
- 可从数据库取回数据
- 可在数据库中插入新的记录
- 可更新数据库中的数据
- 可从数据库删除记录
- 可创建新数据库
- 可在数据库中创建新表
- 可在数据库中创建存储过程
- 可在数据库中创建视图
- 可以设置表、存储过程和视图的权限
- 允许多个人同时操作
SQL相关
- 数据库管理系统(DataBase-Management System,DBMS):由一个相互关联的数据的集合和一组用以访问这些数据的程序组成。这个数据集合通常称作数据库(database)
- 关系型数据库:基于关系模型,使用一系列表来表达数据以及这些数据之间的关系。MySQL就是关系型数据库。
- 关系模型已经成为当今主要的数据模型,它比之前的的网络模型和层次模型简化了编程者的工作。现在开始流行的NoSQL,泛指非关系型的数据库。
Mysql
了解Mysql
Mysql配置文件
- Ubuntu20上通过apt安装的mysql配置文件及目录是/etc/mysql/mysql.conf.d,windows上面是安装目录下的my.ini。如果需要改MySQL的一些设置就需要在配置文件里面去改
查看Mysql服务
- Linux上,通过:
service mysql status - Windows下通过任务管理器即可查看
- 启动Mysql:
service mysql start
登录Mysql
- 输入
mima查询用户名和密码(这是我自己写的命令),出现一个管理员用户和一个普通用户 - 本地连接:
mysql -u用户名 -p密码- 不行展示密码就
mysql -u用户名 -p
- 不行展示密码就
- 远程连接:
mysql -hIP地址 -P端口 -u用户 -p-->>输入密码 - 输入
exit或者quit退出

最重要的SQL命令
- SELECT - 从数据库中提取数据
- UPDATE - 更新数据库中的数据
- DELETE - 从数据库中删除数据
- INSERT INTO - 向数据库中插入新数据
- CREATE DATABASE - 创建新数据库
- ALTER DATABASE - 修改数据库
- CREATE TABLE - 创建新表
- ALTER TABLE - 变更(改变)数据库表
- DROP TABLE - 删除表
- CREATE INDEX - 创建索引(搜索键)
- DROP INDEX - 删除索引
基础语法
- MySQL 语句的规范:
- 关键字与函数名称全部大写
- 数据库名称、表名称、字段名称全部小写,用反引号括起来
- SQL语句必须以分号结尾,表示结束
- 当然不这样也行,只是一种规范
- 查看当前用户:
SELECT USER()
库
- 查库:
SHOW DATABASES - 进入某个数据库:
USE XXX(库名) - 判断在哪个数据库里:
SELECT DATABASE() - 创建数据库:
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] \库名``- 用大括号的部分,就是多选一
- 用中括号的部分, 是可选项
- Mysql中的DATABASE和SCHEMA等效,在其他数据库中可能会有不一样
- 删除数据库:
DROP {DATABASE | SCHEMA} [IF EXISTS] \库名``
补充说明
在MYSQL5.0版本之后,MySQL默认在数据库中存放一个"information_schema"的数据库,是mysql自带的一个信息数据库,保存着关于MySQL服务器所维护的所有其他数据库的信息。
- 该数据库中可利用的表
SCHEMATA表存储该用户创建的所有数据库名的库名。
- schema_name字段用来存储数据库名
TABLES表:储存了数据库的库名以及各个数据库中的表名等信息,可以根据数据库的库名查询到该数据库包含的表有哪些。schema_name表:储存了所有数据库的库名table_schema表:储存了数据库名tables表:储存了数据库库名,以及该库中包含的表名table_schema表:储存了数据库名table_name表:储存了表名- 库名为:TABLES_SCHEMA,表名为:TABLE_NAME,字段名为:COLUMN_NAME.
- 注:表和字段可能具有相对性
表
- 查表:
SHOW TABLES [FROM \库名`]` - 查看当前数据库中的数据表:
SHOW TABLES - 创建表:
CREATE TABLE [IF NOT EXISTS] table_name(
->column_name data_type,
->column_name data_type,
->column_name data_type,
...);
- column_name是字段名,也就是列名
- data_type是字段类型,常见字段类型有整型和字符串
- 查看表的创建信息:
SHOW CREATE TABLE tb_name - 修改表名:
ALTER TABLE \tb_name1` RENAME `tb_name2`` - 查看表字段结构:
DESCRIBE tb_name- 可简写为:
DESC tb_name
示例:
- 可简写为:
mysql> DESCRIBE `student`;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
# Field:字段名
# Type:字段类型
# Null:非空约束,即字段能否为空值
# Key:键约束
# Default:约束
# Extra:其他约束
- 删除表:
DROP TABLE table_name
字段
- 查字段
SHOW COLUMNS FROM tb_name
# 添加字段
ALTER TABLE `tb_name` ADD [COLUNM](
->`col_name` column_definition(data_type),
->`col_name` column_definition,
......);
# 删除字段
ALTER TABLE `tb_name` DROP `col_name`,DROP `col_name`,......;
# 修改字段类型
## 法一:
### MODIFY:修改列的数据类型
ALTER TABLE `tb_name` MODIFY `col_name` data_type;
## 法二:
### CHANGE:改列名和数据类型
ALTER TABLE `tb_name` CHANGE `col_name1` `col_name2` data_type;
数据
# 查看数据
SELECT * FROM `tb_name`;
SELECT `col_name1`,`col_name2` FROM `tb_name` [WHERE ...]
# 插入数据
## 字段值是字符串类型的用单/双引号引起来,不然会报错
INSERT [INTO] `table_name`[(`col_name1`,`col_name2`,...)]{VALUES|VALUE} ({expr|DEFAULT}),(expr|DEFAULT),(...)...;
### 插入多个字段值用VALUES
#### 示例
INSERT INTO `student`(`id`,`name`)VALUES(1,'lili'),(2,'lisa');
### 如果不指定字段就要为所有字段匹配字段值
#### 示例
INSERT INTO `tb_name`VALUES(,,,,,)
# 更新数据
UPDATE `tb_name` SET `col_name1`={expr1|DEFAULT} [WHERE ...] [OR ...] [AND ...]
##更新数据时,如果不用WHERE限定条件,就会更改字段的所有字段值
# 删除数据
DELETE FROM `tbl_name` WHERE where_conditon;
## 相同数据???
常用的数据类型
MySQL 支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。
| 数值类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
|---|---|---|---|---|
| INT或INTEGER | 4 Bytes | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) | 大整数值 |
| BIGINT | 8 Bytes | (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) | 极大整数值 |
| FLOAT | 4 Bytes | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | 单精度 浮点数值 |
| DOUBLE | 8 Bytes | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 双精度 浮点数值 |
| 日期/时间类型 | 大小(bytes) | 范围 | 格式 | 用途 |
|---|---|---|---|---|
| DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
| TIME | 3 | '-838:59:59'/'838:59:59' | HH:MM:SS | 时间值或持续时间 |
| YEAR | 1 | 1901/2155 | YYYY | 年份值 |
| DATETIME | 8 | '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' | YYYY-MM-DD hh:mm:ss | 混合日期和时间值 |
| TIMESTAMP | 4 | '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYY-MM-DD hh:mm:ss | 混合日期和时间值,时间戳 |
| 字符串类型 | 大小 | 用途 |
|---|---|---|
| CHAR | 0-255 bytes | 定长字符串 |
| VARCHAR | 0-65535 bytes | 变长字符串 |
| TEXT | 0-65 535 bytes | 长文本数据 |
表约束与表关系
表约束
- 可以在创建时或创建后添加
- 尽量不要在有数据的时候添加,不然数据和约束冲突就会报错
- 约束就是规定字段存储数据的规则
# 参照示例
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(20) | NO | UNI | NULL | |
+-------+-------------+------+-----+---------+-------+
# NULL:非空约束,YES表示可以为空,NO表示不能为空
# Key:UNI表示添加了唯一约束,PRI表示添加了主键约束,MUL表示添加了外键约束
# Default:默认约束
# Extra:自增约束
非空约束
- 约束数据库字段的某个值是否可以为空
NULL列的字段为YES则可以为空,NO则字段值不能为空- 当字段设置为非空时,插入值就必须要插入值,否则就会报错
- 添加非空约束:
ALTER TABLE MODIFY \col_name` data_type NOT NULL` - 注意:要删除的字段值为NULL的时候,不能用
=来判断,要用IS - 删除非空约束:
ALTER TABLE MODIFY \col_name` data_type`
唯一约束
- 字段添加唯一约束之后,该字段的值不能重复,也就是该字段的值在该表中唯一
- 不提供约束名就默认约束名为字段名
# 添加唯一约束
ALTER TABLE `tb_name` ADD [CONSTRAINT[symbol]]UNIQUE [INDEX|KEY] [index_name] [index_type](index_col_name)
## 示例:
ALTER TABLE `tb_name` ADD UNIQUE `other_name` (`col_name`);
### 创建唯一约束的时候要给约束一个约束名
# 删除唯一约束
ALTER TABLE `tbl_name` DROP {INDEX|KEY}(一般用KEY) index_name(即other_name)
## 示例:
ALTER TABLE `tb_name` DROP KEY `other_name`
主键约束
- 即非空+唯一,一张表只能存在一个主键
- 主键保证记录的唯一性,自动为
NOT NULL - 真主键:
NOT NULL+PRI KEY - 伪主键:
NOT NULL+UNI KEY,表中没有主键时会默认这个伪主键为主键,表中表现为NOT NULL+PRI KEY此时删除就要按照主键的规格来删- 如果此时添加一个真主键,伪主键就会改回
NOT NULL+UNI KEY - 如果添加过真主键,真主键被删除后删除伪主键不能按照主键的规格删
- 如果此时添加一个真主键,伪主键就会改回
# 添加主键约束
ALTER TABLE `tb_name` ADD [CONSTRAINT[sysbol]]PRIMARY KEY [index_type] (index_col_name)
## 示例:
ALTER TABLE `tb_name` ADD PRIMARY KEY(`col_name`)
# 删除主键约束
ALTER TABLE `tb_name` DROP PRIMARY KEY
## 注意:删除主键约束后非空约束会留下
自增约束
- 即自增长,只能添加在主键上
- 伪主键也可以添加自增约束
- 自动编号,默认情况下,初始值为1,每次的增量为1
- 初始值只能在创建表的时候设置
- 自增长约束只能有一个
# 添加自增约束:
ALTER TABLE `tb_name` CHANGE `col_name` `col_name` data_type AUTO_INCREMENT{=num};
# 删除自增约束:
ALTER TABLE `user` CHANGE `id` `id` INT NOT NULL ;
默认约束
- 添加数据的时候如果没有给该字段设置值,则会有一个默认值存在
- 法一:
ALTER TABLE tb_name ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}- 示例:
ALTER TABLE tb_name ALTER col_name SET DEFAULT XXX
- 示例:
- 法二:
ALTER TABLE tb_name MODIFY col_name data_type DEFAULT XXX
创建表的时候添加约束
CREATE TABLE `students`(
->`id` INT PRIMARY KEY AUTO_INCREMENT,
->`name` VARCHAR(20) NOT NULL,
->`age` INT DEFAULT 18,
->`phone` CHAR(20),UNIQUE `phone_uni`(`phone`))
AUTO_INCREMENT=100;
表关系
- 这里的关系指的是数据在逻辑上,人赋予的关系
- 比如:每一人用户表里面存放用户的重要信息, 再定一个用户信息详细表,用来存放用户的详细信息,这个详细信息表就是用户表的就存在一个一对一的关系
- 一对一关系: 如用户表对应用户的详细信息,指的是一个实体的某个数据与另外一个实体的一个数据有关联关系
- 建议添加唯一外键:给其中一张表添加外键,但这个外键必须要有唯一约束
- 一对多关系: 如一个学院当中,有若干学生,指的是一个实体的某个数据与另外一个实体的多个数据有关联关系
- 外键只能建立在多的那张表
- 添加数据时先添加父表(一),再添加子表(多)
- 删除数据时先删除子表,再删除父表
- 多对多关系: 如课程和学生之间,一个课程有很多学生,一个学生对应很多课程,一个实体的数据对应另外一个实体的多个数据,另外实体的数据也同样对应当前实体的多个数据
- 对于多对多关系,需要创建第三张关系表(C),关系表中通过外键加主键的形式实现这种关系。这里需要注意的是
- 在多对多关系中,我们常用中间表来表示
- 表A和表B对表C的关系分别都是一对多
- 联合主键+双外键
外键约束
- 是对其他表的约束
- 可以把两张表联系起来,关联两张表的字段
- 外键列和参照列数据类型一致
- 外键必须关联到键上面去
# 查看所有外键
SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE CONSTRAINT_SCHEMA = 'mydb' AND CONSTRAINT_NAME != 'PRIMARY';
# 添加外键
ALTER TABLE tb_name(需要添加外键的表) ADD [CONSTRAINT 外键名] FOREIGN KEY [id] (index_col_name, ...) REFERENCES tb_name(要参考的表) (index_col_name, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}](删除时发生什么操作) /
[ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}](更新时发生什么操作)
## CASCADE 删除包含与已删除键值有参照关系的所有记录
## SET NULL 修改包含与已删除键值有参照关系的所有记录,使用NULL值替换(只能用于已标记为NOT NULL的字段)
## RESTRICT 拒绝删除要求,直到使用删除键值的辅助表被手工删除,并且没有参照时(这是默认设置,也是最安全的设置)
## NO ACTION同 RESTRICT 也是首先先检查外键; (拒绝删除或者更新父表)
### 示例:
ALTER TABLE `student` ADD FOREIGN KEY (`dept_id`)(要添加外键的字段) REFERENCES `department`(`d_id`) ON DELETE SET NULL
联合主键
- 两个字段的组合不能出现重复值
ALTER TABLE tb_name ADD PRIMARY KEY(col1_name,col2_name)
数据库三范式
- 第一范式(1NF):符合1NF的关系中的每个属性都不可再分。
- 1NF是所有关系型数据库的最基本要求
- 简单来说,就是不能出现多个表头
- 第二范式(2NF):2NF在1NF的基础之上,消除了非主属性对于码的部分函数依赖
- 简单来说,只能描述一个对象(主键),其它列名(副键)与对象之间相互完全依赖
- 第三范式(3NF):3NF在2NF的基础之上,消除了非主属性对于码的传递函数依赖
- 简单的说,所有的非主属性只在整个数据库里面出现一次,副键与副键之间,不能存在依赖关系范式的作用是尽可能避免数据的冗余和插入/删除/更新的异常
表查询
视图
- 三范式让表查询变得复杂,对于常用的数据查询,反复写复杂的查询语句十分不方便,因此可以创建一个虚拟的表(不存数据)
- 这个虚拟表的数据来源于数据库中存在的其他表,虚拟表的数据来源就在定义时给定,源表被改动该表也会改动
# 创建视图
CREATE [OR REPLACE] VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION]
## 示例:
CREATE VIEW `view_name` AS SELECT * FROM `tb1_name` RIGHT JOIN `tb2_name`
# 删除视图
DROP VIEW view_name
事务(非常重要)
- 遵循原子性,即多条SQL语句当作一条执行,如果有一条失败则都会失败
- 遵循一致性,即多个并行事务执行结果必须按照某个顺序串行执行
- 遵循隔离性,即事务的执行不受其他事务影响
- 遵循持久性,即事务处理结束后,对数据的修改是永久的
- 关键字:
BEGIN:开始ROLLBACK:回滚COMMIT:提交/确认
BEGIN;# 固定数据
SQL语句
ROLLBACK;# 回滚到BEGIN时候的数据状态
COMMIT;# 确认操作,此时回滚不会再回到BEGIN的数据状态
单表查询
SELECT * FROM tb_name;- SELECT 后面跟上要查询的字段,* 号代表所有的字段
- 一般来说,查询所有字段是最耗时长的,所以今后查询数据尽可能按需所取。
- 条件查询:条件查询条件可以是大于等于不等于(
>,=,<>)等等,也可以是更加复杂的判断都是可以的。- 示例:
SELECT col_name FROM tb_name WHERE xxx
- 示例:
- 取别名:如果列名或者表名太长,可以给它们取一个别名,可以方便取使用
SELECT col_name AS new_name FROM tab_name AS new_name2
- 行查询:
SELECT * FROM tb_name\G;- 按行显示数据
- 模糊查询:()代表或者,这个查询相当于正则查询
- 示例:
SELECT * FROM stu WHERE si_age IN (19,30)查询19或30的数据 LIKE关键词的查询更加模糊- 示例:
SELECT * FROM tb_name WHERE col_name LIKE 'L%' - 查询某字段所有匹配
L...的数据 %代表通配符_匹配一个字符
- 示例:
- 示例:
- 区间表示:
- 示例:
SELECT * FROM stu WHERE si_age BETWEEN 19 AND 30 - 用大于号小于号也行
- 示例:
多表查询
内连接
- 笛卡尔坐标系:把两张表想象成X轴和Y轴,轴上的每个点,就是两个表里面的每行数的集合
SELECT * FROM `department` INNER JOIN `students`;
SELECT * FROM `department` , `students`;
SELECT * FROM `department` CROSS JOIN `students`;
SELECT * FROM `department` JOIN `students`;
## 以上这个四个SQL的结果都一样,都是笛卡尔积,也叫无条件连接/交叉连接等,不推荐,比较耗内存
注意在mysql中,INNER JOIN 和 CROSS JOIN 是一样的。
# 当然也是可以
SELECT * FROM `department` INNER JOIN `students` ON `department`.`d_id` = `students`.`dept_id`;
SELECT * FROM `department` INNER JOIN `students` WHERE `department`.`d_id` = `students`.`dept_id`;
SELECT * FROM `department` p , `students` s WHERE p.`d_id`=s.`dept_id`;
SELECT * FROM `department` p CROSS JOIN `students` s WHERE p.`d_id` = s.`dept_id`;
SELECT * FROM `department` AS `p` , `students` AS `s` WHERE p.`d_id`=s.`dept_id`;
## 这是有条件连接
## WHERE相比于ON在数据量较大的时候比较占内存
外连接
左连接
A LEFT JOIN B会以左边的表为主,展式左边表的所有数据,展式右边表中符合ON子句中条件的数据,没有为NULLSELECT * FROM 第一张表 LFET JOIN 第二张表 ON 主表.s_id=sd.stu_id;
右连接
SELECT * FROM 第一张表 RIGHT JOIN 第二张表 ON 主表.s_id=sd.stu_id;
全连接
- UNION操作符
- UNION 操作符用于合并两个或多个 SELECT 语句的结果集
- 它可以从多个表中选择数据,并将结果集组合成一个结果集
- 使用 UNION 时,每个 SELECT 语句必须具有相同数量的列,且对应列的数据类型必须相似
- 即被拼接两张表的字段数要相同
- UNION 操作符默认会去除重复的记录,如果需要保留所有重复记录,可以使用 UNION ALL 操作符
- 即两张表拼接然后消除重复的内容
语法:
SELECT column1, column2, ...
FROM table1
UNION
SELECT column1, column2, ...
FROM table2;
# 示例1:
SELECT s.`name`,c.`name` FROM `students` s LEFT JOIN `select` se ON s.`s_id`=se.`stu_id` LEFT JOIN `course` c ON c.`id`=se.`coures_id`
UNION {ALL}
SELECT s.`name`,c.`name` FROM `students` s LEFT JOIN `select` se ON s.`s_id`=se.`stu_id` LEFT JOIN `course` c ON c.`id`=se.`coures_id`;
# 示例2:
SELECT s.`name`,c.`name` FROM `students` s LEFT JOIN `select` se ON s.`s_id`=se.`stu_id`
UNION {ALL}
SELECT s.`name`,c.`name` FROM `students` s RIGHT JOIN `select` se ON s.`s_id`=se.`stu_id`
子表查询
- 在一个SQL语句中出现两个SQL语句,就是子表查询
- 把一个命令的结果作为条件给另一个命令使用
- 子表结果只有为一行的时候才能传递给WHERE
- 下面这个子表查询是在JOIN这个地方建立查询
# 示例1:
SELECT s.`name`, e.`name`FROM `students` s
LEFT JOIN(
SELECT se.`stu_id`,c.`name` FROM `select` se JOIN `course` c ON se.`coures_id` = c.`id` ) e
ON s.`s_id`=e.`stu_id`;
# 示例2:
SELECT * FROM `stu` WHERE `dept_id`=(
SELECT `d_id` FROM `department` WHERE `d_name`='PYTHON');
对结果集排序:ORDER BY
SELECT * FROM table_name
ORDER BY column_name [ASC|DESC]
ASC: 升序(默认)。DESC: 降序。
限制行数:LIMIT
- 对查询出来的结果限制显示的行数
示例:
SELECT * FROM `students` s JOIN `student_details` sd ON s.`s_id`=sd.`stu_id` ORDER BY s.`s_id` DESC LIMIT 3;
分组查询
- 分组是个常见的操作,常用于分组统计
- 使用
GROUP BY后,会按照GROUP BY后面的字段进行分组,且必须是明确的字段,不能是*GROUP BY后面不能通过WHERE来筛选
- 因此
SELECT后面也不能是* - 其次可以使用
HAVING可以对分组之后的结果进行筛选- 注意:HAVING 后的字段必须是SELECT后出现过的
- 示例:
SELECT d.`d_id`,d.`name`,COUNT(*) FROM `department` d LEFT JOIN `students` s ON d.`d_id`=s.`dept_id` GROUP BY d.`d_id`,d.`name`;
# COUNT(*)统计该字段下各个数据分布的数据量
SELECT d.`d_id`,d.`name`,COUNT(*) FROM `department` d LEFT JOIN `students` s ON d.`d_id`=s.`dept_id` GROUP BY d.`d_id`,d.`name` HAVING COUNT(*)>1;
AND & OR 运算符
如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。
如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。
Mysql函数
处理NULL(IFNULL)
SELECT IFNULL(`col_name`,430)(如果该字段的数据为NULL则返回后面那个值) FROM `tb_name`
字段去重(DISTINCT)
- 得到该字段不重复的的数据
SELECT DISTINCT `name` FROM `students`
字符串截取
LEFT是从左边开始截取,RIGHT是用右边开始截取,SUBSTRING可以指定截取范围
SELECT LEFT(`col_name`,2),IFNULL(`col_name`,430) FROM `students`
# 截取数据左边两个字符
SELECT RIGHT(`col_name`,2),IFNULL(`col_name`,430) FROM `students`
SELECT SUBSTRING(`col_name`,2,5),IFNULL(`col_name`,430) FROM `students`
字符串拼接(CONCAT)
SELECT CONCAT(s.`name`,sd.`id_card`) FROM `students` s LEFT JOIN `student_details` sd ON s.`s_id`=sd.`stu_id`;
类型转换
SELECT CAST(sd.`id_card` AS CHAR) FROM `students` s LEFT JOIN `student_details` sd ON s.`s_id`=sd.`stu_id`;SELECT CONVERT(s.`dept_id`,SIGNED) FROM `students` s ;
时间函数
SELECT DAY('2017-08-18')-DAY('2017-08-01’);
SELECT NOW();
SQL优化
执行顺序(不怎么重要)
1.FROM: 对FROM的左边的表和右边的表计算笛卡尔积。产生虚表VT1
2.ON: 对虚表VT1进行ON筛选,只有那些符合<join-condition>的行才会被记录在虚表VT2中
3.JOIN: 如果指定了OUTER JOIN(比如left join、 right join),那么保留表中未匹配的行就会作为外部行添加到虚拟表VT2中,产生虚拟表VT3, rug from子句中包含两个以上的表的话,那么就会对上一个join连接产生的结果VT3和下一个表重复执行步骤1~3这三个步骤,一直到处理完所有的表为止。
4.WHERE: 对虚拟表VT3进行WHERE条件过滤。只有符合<where-condition>的记录才会被插入到虚拟表VT4中
5.GROUP BY: 根据group by子句中的列,对VT4中的记录进行分组操作,产生VT5.
6.CUBE | ROLLUP: 对表VT5进行cube或者rollup操作,产生表VT6.
7.HAVING: 对虚拟表VT6应用having过滤,只有符合<having-condition>的记录才会被 插入到虚拟表VT7中。
8.SELECT: 执行select操作,选择指定的列,插入到虚拟表VT8中。
9.DISTINCT: 对VT8中的记录进行去重。产生虚拟表VT9.
10.ORDER BY: 将虚拟表VT9中的记录按照<order_by_list>进行排序操作,产生虚拟表VT10.
11.LIMIT:取出指定行的记录,产生虚拟表VT11, 并将结果返回。
查找优化
- 要想SQL执行快一点,应该尽量避免模糊匹配,如:like, in, not in 等这些匹配条件
- 尽量避免整表扫描,如
SELECT * - 建立合适的索引3
- 使用合适的存储引擎
- 在JOIN中,尽量用小表LEFT JOIN 大表
- 除非十分必要,尽量不要使用ORDER BY,GROUP BY 和 DISTINCT(去重),尽量用索引来代替

浙公网安备 33010602011771号