我不会记录的特别详细
大体框架
- 基本的Select语句
- 运算符
- 排序与分页
- 多表查询
- 单行函数
- 聚合函数
- 子查询
第三章 基本的SELECT语句
SQL分类
这个分类有很多种,大致了解下即可
- DDL(Data Definition Languages、数据定义语言),定义了不同的数据库、表、视图、索引等数据库对象,也可以用来创建、删除、修改数据库和数据表的结构。
常见的CREATE
、DROP
、ALTER
- DML(Data Manipulation Language、数据操作语言),用于添加、删除、更新和查询数据库记录,并检查数据完整性。
主要包括INSERT
、DELETE
、UPDATE
、SELECT
等。SELECT
用的最多. - DCL(Data Control Language、数据控制语言),用于定义数据库、表、字段、用户的访问权限和安全级别。
主要包括GRANT
、REVOKE
、COMMIT
、ROLLBACK
、SAVEPOINT
等。
SQL的规则与规范
规则
这个必须遵守
- 每条命令以;或\g或\G结束
- 关键字不能被缩写也不能分行,更不能在中间插入空格,如select写成sel ect,错误
- 字符串和日期时间类型的数据可以使用单引号(‘’)表示
- 列的别名用双引号(“”),建议加上as
规范
- windows下对大小写不敏感
- Linux下大小写敏感,比如数据库名大写和小写不一样,但是关键字、函数名、列名及其别名是忽略大小写的
- 推荐的规范
- -SQL关键字、函数名、绑定变量都大写,其余的都小写
注释
单行注释 #和–,多行注释 /**/
# 单行注释
-- 单行注释
/*多行注释
*/
命名规则
这个了解即可
- 库名,表名不得超过30个字符,变量名限制为29个字符
- 同一个MySQL软件中,库名必须唯一,同一个库中,表名必须唯一,同一个表中,字段名唯一
- 若关键字与字段名冲突且坚持使用,用着重号(``)把字段引起来
例子
create database a;//正确
create database a;//错误,已经存在
use a;
create table order(id int);//错误,order是关键字
create table `order`(id int);//正确
数据导入指令
source sqlFile
基本的Select语句
select … from TableName;
为什么不推荐使用*
因为获取所有的列会降低性能,让效率变低
列的别名
就比如你要计算年工资,你总不能存一个年工资和月工资把,这样浪费空间,还不是起一个别名
注意事项
别名使用双引号,列名和别名之间加入AS,若别名有空格必须使用双引号,别名要见名知义
例子:
SELECT name,salary,salary * 12 AS "annual salary" FROM employee;
DISTINCT
去重的,对所在列以及后面的列去重
例如:
SELECT DISTINCT departmentId From employee;//对departmentId进行去重
SELECT DISTINCT departmentId,salary FROM employee;//对部门id和工资这个组合进行去重
/*
若有两条记录
departmentId salary
1 8000
1 7800
那么这两条记录会保留
若两条记录是
departmentId salary
1 8000
1 8000
这个是保留一个
*/
NULL参与运算
只要有NULL结果必定为NULL
注意:NULL不是空,他占存储空间,NULL的长度为空
查询常数
这个我没有试过,明天试试
就比方说我想要把公司A的所有部门都列出来,格式如下:
公司A | 部门名称 |
---|---|
公司A | 部门1 |
公司A | 部门2 |
公司A | 部门3 |
可以这么写
SELECT "公司A",departmentName from deparments;
显示表结构
DESC或者DESCRIBE
DESCRIBE departments;
desc departments;
结果中有两列是Key和Extra,只记录这两个
- Key:表示该列是否已编制索引。PRI表示该列是表主键的一部分(主键可以有多个列组成);UNI表示该列是UNIQUE索引的一部分(复合索引);MUL表示在列中某个给定值允许出现多次。
- Extra:该列的附加信息,例如AUTO_INCREMENT等等
where
这个太简单了,不记录了
第四章 运算符
算数运算符
加->+
减->-
乘->*
除->/
取余->%,比如 17 % 5 = 2 (17 -3*5)
比较运算符
这个很简单,简要记录
真为1,假为0,其他为null
- 不等于:<>,!=
- 大于(等于):>(>=)
- 小于(等于):<(<=)
等号运算符
- 若两边都是字符串,比较的是ASCII码是否相等
若是整数就是比较数值大小 - 若一个是字符串,另一个是整数,MySQL会把字符串转换为数字进行比较
- 若有一个为null,那么结果必定为null
安全等于运算符 <=>
他比等于多一个对null的判断,只有他是针对null的,就是当两边都是null的时候返回1;一边为null一边不为null返回0
SELECT NULL <=> NULL, 1<=>1;
逻辑运算符
与或非,异或没了,这里简单记录,
注意这里只要有一个参数是NULL那么结果必定为NULL,优先级:NOT > AND > OR(XOR)
运算符 | 规则 | 例子 |
---|---|---|
NOT 或! | 若为0结果为1,若为1,结果为0 | SELECT NOT |
AND 或 && | 同一则一,有一个0就是0 | SELECT 1 && 1 |
OR 或 || | 有一个一就是一,全为0结果就是0 | SELECT 1 OR 0 |
XOR | 两个不一样就是1,一样就是0 | SELECT 1 XOR 0 |
位运算符
我的理解就是把操作数转换为补码按照指定的运算符的规则进行运算,再把结果转换为十进制数字
支持的运算符
运算符 | 含义 | 例子 |
---|---|---|
& | 按位与(AND) | SELECT A & B |
| | 按位或(OR) | SELECT A | B |
^ | 按位异或(XOR) | SELECT A ^ B |
~ | 按位取反 | SELECT ~A |
>> | 按位左移 | SELECT A <<1 |
<< | 按位右移 | SELECT B >>1 |
解释: 以 8 和-2 为例
8转换为补码是 0 1000
-2的原码是 1 0010
-2的反码是 1 1101
-2的补码是 1 1110
8 & -2
0 1000
& 1 1110
——————
0 1000
这里直接转二进制即可,结果是8
8 | -2
0 1000
| 1 1110
——————
1 1110
最高位是1,是负数,要求真值,对1 1110取补等于1 0010 转换为二进制数为-2 ,但是显示的结果是18446744073709551614
,应该是默认情况下数字以bigint类型存储的,bigint类型是8个字节,他的结果解释方式应该是把二进制解释成无符号数,要不然不会这么大的数字,如果是按照这么来的话,那1 1110
需要进行符号位扩展,扩展如下
1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110
,就是在1 1110
的最高位1前面加了79个1,把这一串数字转换为十进制等于18446744073709551614
8 ^ -2
0 1000
| 1 1110
——————
1 0110
符号位扩展,扩展成64位,扩展结果
1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0110
,把这东西转换为十进制18446744073709551606
~ -2
-2的补码(64位)等于1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110
# 1111 1111 -> 0000 0000
# 1111 1111 -> 0000 0000
# 1111 1111 -> 0000 0000
# 1111 1111 -> 0000 0000
# 1111 1111 -> 0000 0000
# 1111 1111 -> 0000 0000
# 1111 1110 -> 0000 0001
# 从上到下,把->后面的数字串起来为1前面63个0,当成无符号数,转换为十进制为1,所以答案就是1
1 >> 2
tips:在一定的条件下,可以当作除以2的n次幂来用
右移的规则:右移指定的位数后,右边低位的数值被移出并丢弃,左边高位空出的位置用0补齐。
这里不做符号位扩展了,简要的记录一下
1的补码是0 1,右移一位,01的最低位1就没了,高位补零,那么直接移成了0
1 << 2
tips: 在一定的条件下,可以当成乘以2的n次幂来用
就是乘以了2n,n就是右移的位数,可能会溢出
优先级
其他运算符
- IS NULL: 判空的
- IS NOT NULL:判非空的
- LEAST:返回多值中的最小值
SELECT LEAST(1,2,3,4) FROM DUAL;
- GREATEST:返回多值中的最大值
SELECT GREATEST(1,2,3,4) FROM DUAL;
- BETWEEN AND:判断值是否在指定的区间内,区间是左闭右闭的
SELECT 2 between 1 and 2;
- ISNULL:判空
- IN: 判断一个值是否为列表中的任意一个值
一般是在子查询里面用的比较多
SELECT 2 NOT IN (1,2);
- NOT IN:判断一个值是否不是一个列表中的任意一个值
SELECT 2 NOT IN (1,2);
- LIKE 运算符:匹配字符串的,模糊匹配
%是通配零个或多个字符的
_是只能匹配一个字符的
SELECT 'abcd' LIKE 'a__d';
- ESCAPE:回避特殊符号的,\也可以
比方说,查找前两个字符是EM,第三个字符是%或者_的
:取消_,%的匹配作用
ESCAPE:指定一个字符充当\的作用,这个言简意赅点,
指定字符后面紧挨着的第一个匹配符号(_,%)失效,这个不太常用
SELECT DepartmentId FROM DEPT WHERE DepartmentId like 'EM\%'or DepartmentId like 'EM\_';//这个用的比较少,了解
SELECT DepartmentId FROM DEPT WHERE DepartmentId like 'EMa%' ESCAPE 'a'or DepartmentId like 'EMb_' ESCAPE 'b';
- REGEXP运算符
这里要用到点正则表达式的东西,这个用到了去网上搜
正则表达式简要了解下,这东西能写出一本书出来
‘^’:匹配以该字符后面的字符开头的字符串
‘$’:匹配以该字符前面的字符结尾的字符串
'. ': 匹配任何一个但字符
“[…]”:匹配出现在方括号里面的字符,如匹配所有字母:[a-zA-Z]
‘*’:匹配零个或多个在它前面的字符,
扩展 正则表达式
常应用于检索字符串,提取数字,验证等等
MySQL支持的
- 查询以特定字符或字符串开头的记录:
在name列查询以ea开头的记录
SELECT * FROM `user` where name REGEXP '^ea';
- 查询以特定字符或字符串结尾的记录:
在name列查询以or结尾的记录
SELECT * FROM `user` where name REGEXP 'or$';
- 用符号’.'通配一个字符,查询name列字段值中包含ea且e和a之间只有一个字母的记录
SELECT * FROM `user` where name REGEXP 'e.a';
- 用’*‘和’+'匹配多个字符:在name列中查找以字母c开头且c后面出现字母e至少一次的记录
SELECT * FROM `user` where name REGEXP '^ce+';
- 匹配指定字符串,可以匹配多个
- 在name列中查找包含ea的记录
SELECT * FROM `user` WHERE name REGEXP 'ea';
- 在name列中查找包含ea和or的记录
SELECT * FROM `user` WHERE name REGEXP 'ea | or';
- 匹配指定字符中任意一个,就是方括号的用法
在name列中查找包含字母abced和 wxy的记录
SELECT * FROM `user` WHERE name REGEXP '[a-dw-y]
- 匹配指定字符以外的字符 "[^字符集合]"匹配不在指定集合中的任何字符
在name列中查找id字符串包含a-h和数字1-8以外字符的记录
SELECT * FROM `user` WHERE id REGEXP '[^a-h1-8]';
- 使用{n,}或者{n,m}来指定字符串连续出现的次数,“字符串
{n,}
”表示至少匹配n
次前面的字符;“字符串{n,m}
”表示匹配前面的字符串不少于n
次,不多于m
次。例如,or{2,}
表示or连续出现至少2
次,也可以
大于2
次;ea{2,4}
表示ea连续出现最少2
次,最多不能超过4
次。
运算符一章完成,明天完成排序的一半