SQL概念
SQL语句分类
- 数据定义语言DDL(DataDefinition Language)
a. 作用:对容器的创建、修改、删除【库、表、列】
b. 关键字:create(创建)、alter(改建)、drop(丢弃) - 数据操作语言DML(Data Manipulation Language)
a. 作用:对数据插入、修改、删除操作
b. 关键字:insert(插入)、update(修改)、delete(删除)、truncate(截断) - 数据查询语句DQL(Data Query Language)
a. 作用:进行数据库操作查询
b. 关键字:select(选择) - 数据控制语言DCL(Data Control Language)
a. 作用:创建用户,用户赋权、权限收回、删除用户
b. create、rant、revoke、drop - 事务处理语言TPL(Transaction Process Language)
a. 作用:进行数据库事务操作,优化多条DML语句安全问题
b. start、commit、rollback···数据库的基本操作
```plsql SHOW DATABASES; —查询当下所有数据库
CREATE DATABASE <库名>; — 创建数据库
SHOW CREATE DATABASE <库名>; — 查看创建数据库信息
DROP DATABASE <库名>; — 删除数据库(不存在报错)
<a name="Gda87"></a># 数据表的基本操作- 约束- 主键约束:要求主键列数据唯一,并且不允许为空- 联合主键约束:不存在联合主键约束相等的数据- 外键约束:- 关系- 主表(父表)- 从表(子表)- 外键约束模式:两个表数据之间字段建立连接- district:严格模式,不允许操作- cascade:级联模式,一起操作,主表变化,从表数据跟随(删除)- set null:空值模式,父表变化(删除),从表为null(需要从表允许为null)- 非空约束:字段值不允许为null- 唯一性约束:字段值要求是唯一的,允许为null,但只有一个null- 默认约束:数据没有为该字段赋值时,会使用默认字段值- 自增约束:整数类型(TINYINT、SMALLIN、INT、BIGINT),唯一并自增```plsql-- 创建数据表CREATE TABLE <表名>(字段名 数据类型 [列级别约束条件] [默认值],[表级别约束条件]);-- 举例说明CREATE TABLE tb_emp1(id int(11) comment "员工编号",name varchar(25) comment "员工名称",depptId int(11) comment "所在部门编号",salary float comment "工资");-- 主键约束id int(11) primary key comment "员工编号"; -- 定于主键约束PRIMARY KEY(id); -- 指定主键约束-- 联合主键约束PRIMARY KEY(id, name);-- 外键约束CONSTRAINT KEY(id) REFERENCES <主表>(id);-- 非空约束name varchar(25) NOT NULL;-- 唯一性约束name varchar(25) UNIQUE;-- 默认约束name varchar(25) DEFAULT "未命名";-- 自增约束id int(11) PRIMARY KEY AUTO_INCREMENT;-- 检查约束sex char(1) CHECK('男' or '女');-- 查看数据表DESCRIBE 表名; -- 查看数据表数据;简写:DESC 表名SHOW CREATE TABLE 表名\G; -- 查看表创建结构-- 修改字段表ALTER TABLE<旧表名>RENAME<新表名>; -- 修改表名ALTER TABLE<表名>MODIFY<字段名><数据类型>; -- 修改表结构ALTER TABLE<表名>CHANGE<旧列名><新列名><数据类型>; -- 修改列名和结构ALTER TABLE<表名>ADD<列名><数据类型>[FIRST|AFTER<列1>]; -- 新增字段ALTER TABLE<表名>NODIFY<字段名><数据类型>[FIRST|AFTER<列1>];-- 修改字段插入的位置-- FIRST<列1>插入列1前、AFTER<列1>插入列1后、没有列1放最前和最后-- 删除字段ALTER TABLE<表名>DROP<字段>; --删除字段ALTER TABLE<表名>DROP FOREIGN KEY<外键约束名> -- 删除外键约束DROP TABLE [IF EXISTS] 表1,表2,表n; -- 删除没有关联的一个或多个表-- 修改存储引擎ALTER TABLE <表名> ENGINE=<引擎名>; -- 外键约束不能跨引擎使用
数据操作
-- 增INSERT [INTO] <表名> (字段列表) VALUES (值列表),(值列表)...;INSERT [INTO] <表名> VALUE (值列表);-- 删DELETE FROM <表名> [where];-- 改UPDATE <表名> SET key=val [where];-- 查SELECT * FROM <表名>; -- 后面将祥写查询数据
数据类型和运算符
数据类型
常用类型
- 整数
- tinyint 1字节
-128~127/0~255 - smallint 2字节
-32768~32767/0~65535 - int(integer) 4字节
-2*10**9 ~ 2*10**9/0 ~ 4*10**9 - bigint 8字节
-9*10*18~9*10*18/0 ~ 18*10*18 - unsigned(无符号数值)
- tinyint 1字节
- 小数
- float 4字节
- double 8字节
- decimal(m,d) m+2字节
- 时间日期
- year
YYYY1901~21551字节 - time
HH:MM:SS±838:59:593字节 - date
YYYY-MM-DD``1000-01-01~9999-12-33字节 - datetime
YYYY-MM-DD HH:MM:SS``1000-0101 00:00:00 ~ 9999-12-31 23:59:598字节 - timestamp
YYYY-MM-DD HH:MM:SS``1970-01-01 00:00:01 ~ 2038-01-19 03:14:074字节
- year
- 字符
- char(M) 固定长度
- varchar(M) 动态长度,性能略低
对大型文件的存储(图片、声音、网页、文本),虽然有相关的存储方法(blob、text),但会减低服务器的性能 在非必要条件下可以将文件存储其他地方,用文件路径进行引导
条件运算符号
普通运算符= 等于<>(!=) 不等于<= | >= 小于等于 | 大于等于< | > 小于 | 大于<=> 安全等于,与等于相同,但它能判断null,两边为null时才为1特殊比较符IS NULL | ISNULL 判断是否为nullIS NOT NULL 判断是否不为nullBETWEEN V1 AND V2 判断值是否在区间内(含v1,v2)IN(v1,v2) 判断是否在in列表中(左侧和列表内有null,均返回null)NOT IN(v1,v2) 判断是否不在in列表中(左侧和列表内有null,均返回null)LEAST(v1,v2) 返回最小值(有null时返回null)GREATEST(v1,v2) 返回最大值(有null时返回null)LIKE "%_" 通配符匹配% 匹配0到多个字符_ 匹配一个字符REGEXP 正则表达式匹配(与其他正则语法类似)EXISTS(select) 判断是否能查询出数据,如果有数据返回true,否则false大小写如何判断?在Windows的mysql中,是不区分大小写的('a'='A'结果为1)但在字符串前加binary可以区分(BINARY'a'='A'结果为0)
条件拼接符号
and && 逻辑与or || 逻辑或not ! 逻辑非XOR 逻辑异或
MySQL函数
数字函数
abs(x) 绝对值pi() 圆周率(7位小数)sqrt(x) 平方根(负数没有平方根,返回null)mod(x,y) 求余format(x, n) 四舍五入,保留n位小数ceil(x) 向下取整floor(x) 向上取整round(x) 取整四舍五入 round(x,y)保留y位小数truncate(x,y) 截取小数rand() 0-1的随机数,rand(x)种子值,产生重复序列sign(x) 输入负、零、正数,返回-1、0、1pow(x,y) 幂运算
字符串函数
-- 查char_length(str) 字符串的个数length(str) 返回字节长度(utf8时汉字为3字节)left(s,n) 切片字符[0, n)right(s,n) 切片字符[n, end] 截取尾部n个字符substr(s, n) 切片字符(n, end] 第n个开始到结尾substring(s, n, l) 切片字符[n, l] n可以是负数 mid(s,n,l)strcmp(s1,s2) 比较字符串大小locate(s1,s)、position(s1 in s)、instr(s, s1) s1存在存在s的位置elt(n, s1, s2, s3) 指定字符串的位置field(s, s1, s2,s3) s所在的位置find_in_set(s1, s2) s1在s2的位置,用多个,隔开的字符串-- 改concat(s,s,s) 拼接多个字符(遇到null,只返回null)concat_ws(x,s,s) 拼接多个字符(遇到null,用x代替)insert(s, i, l, s) 替换并拼接s原字符串, i开始位(超出原字符位返回原字符串), l替换长度, s替换后字符lower(s),lcase(s) 字母全小写upper(s),ucase(s) 字母全大写mysql没有首字母大写的函数,但可以通过复杂函数来实现首字母大写concat( upper(left(s, 1)), lower(substr(s, 2)) )reverse(s) 翻转replace(s,s1,s2) 替换,s中的s1替换成s2trim(s1 from s) 删除两边的s1值,默认空格lpad(s1, len, s2) s1长度不够len,左边填充s2rpad(s1, len, s2) s1长度不够len,右边填充s2ltrim(s)、rtrim(s)、trim(s) 左侧删除空格、右侧删除空格、两边删除空格-- 生成repeat(s, n) 生成n个s进行拼接space(n) 生成n个空格
时间日期函数
curdate(); current_data(); 获取当前日期-- curdate()+0 当前日期转换成数值型curtime(); current_time(); 获取当前时间-- curtime()+0 当前时间转换成数值型unix_timestamp(); 获取当前时间戳-- unix_timestamp(new()); 时间转时间戳from_unixtime(unix); 时间戳转时间格式year(date);month(date);dayofweek(date);day(date);dayofyear(date);获取 年、月、星期、日、今年的第几天hour(date);minute(date);second(date);获取时、分、秒date_format(date, format);时间转字符datediff(date1, date2);两个时间的隔天数 date1-date2date_add(date, interval expr type);date_sub(date, interval expr type);date时间获取隔间后的时间
条件判断函数
if(expr, v1, v2); 正确返回v1, 错误返回v2ifnull(v1,v2); v1不为null返回v1,否者v2case expr when v1 then r1 [when v2 then r2] else f end; 多分支判断
系统信息函数
version(); 返回版本connection(); 用户连接数database(); 当前数据库user(); 当前用户processlist; 当前用户连接状态
加密函数
md5(str); md5加密sha(str); sha加密sha2(str, len); 加密长度(支持长度:224、256、384、512)
其他函数
conv(n, f, b); f进制转b进制
窗口函数
select *, rank() over w1 as `rank` from branchwindow w1 as (order by brcount);生成排名select * , (brcount) / (sum(brcount) over()) as rate from branch;每个部门人数占总人数的百分比
事务处理
show variables like "%autocommit%";
查询数据
查询语句基本结构
select [distinct]{ * | <字段列表> }[from <表1>,<表2>...[where <表达式>][group by <group by definition>][having <expression> [{<operator> <expression>...}] ][order by <order by definition>][limit [offset, ] <row couunt>]]
where限定查询必须满足查询条件group by查询出来的数据按照指定字段分组having与group by一起使用,筛选分组后的数据order by查询出来的数据按照顺序进行显示(asc升序,desc降序)limit查询出来的数据每次显示的区域单表查询
```plsql select { * | <字段列表> } from 表名; — 获取不需要的列数据会 减低查询和应用程序的效率
select * from 表名 where <条件判断>;
— 条件过滤
select * from 表名 where <条件判断> order by <字段>[,<字段>] [def asc | desc]; — 字段排序
select distinct <字段v> from 表名; — 字段v不重复
<a name="ZBuT5"></a>## 聚合查询```plsqlselect <字段> count(*) from 表名 group by <字段>;aggregate函数avg(); count(); sum();平均值; 行数; 总数first(); last(); max(); min();第一个记录值; 最后一个记录值; 最大值; 最小值-- MAX(), MIN()可以对时间进行聚合COALESCE(expression [ ,...n ])返回从头到为第一个不为null的值group_concat(v [order by v, SEPARATOR ","]); -> v, v[order by排序, SEPARATOR分隔符]json_objectagg(k, v); -> {k: v, k: v}json_arrayagg(v); -> [v, v]
count(*) 、count(0)、count(1) 、 count(列名) 的区别?
- count(0) = count(1) = count(*) 不忽略null值和空值
- count(列名) 忽略null值
- count(*) 会自动帮你完成优化
- 列名为主键时效率上:count(列名) > count(1)
- 列名不为主键时效率上:count(列名) < count(1)
- 如果有多字段并且没有主键效率上:count(1) > count(*)
- 如果表只有一个字段时:count(*) > count(1)
