目录
- 前言
- 一、MySQL的安装以及基本命令
- 1.1安装
- 1.2基本命令
- 二、基本查询
- 2.1 基本查询语法
- 2.2 筛选条件分类
- 2.3 排序
- 2.4 聚合函数
- 2.5 分组
- 三、常见函数
- 3.1 字符串函数
- 3.2 数学函数
- 3.3 日期函数
- 3.4 其他函数
- 四、多表连接
- 4.1 内连接
- 4.2 外连接
- 五、子查询
- 5.1 分类
- 5.2 where或having后的子查询
- 5.3 select后面的子查询
- 5.4 from后面
- 六、联合查询
前言
本篇文章主要是给已经有了mysql基础(一丢丢基础也行)的同学用来查漏补缺的,主要记录了一些常用方法以及它们的一些注意点(都是踩坑的教训),同时也记录了自己对一些概念的理解,比如分组啊,内连接、外链接等等,希望各位道友不吝赐教,大家一起交流进步!
一、MySQL的安装以及基本命令
1.1安装
安装这里转载一篇别人写的博客吧,写的非常详细大家可以参照她的
安装MySQL教程
1.2基本命令
- 启动和停止服务
net start 服务名 和 net stop 服务名 - mysql的登录和退出
mysql 【-h 主机名 -P 端口号】 -u 用户名 -p密码 (登录)
ctrl + c 或 exit (退出)
二、基本查询
2.1 基本查询语法
select 字段1 【别名1】,字段2 【别名2】from 表【where 筛选条件】
注意:数据库的执行顺序并不是从select开始一直执行到末尾,它的顺序是这样的。
- 先看from后面的表,知道在哪个容器(表)中查找我们需要的记录。
- 在用where中的筛选条件用来对容器中的记录进行过滤
- 最后再选择select后跟着的字段名的那几列作为我们的查询结果。
2.2 筛选条件分类
- 简单条件运算符:=、!=、>、<、>=、<=
- 逻辑运算符:&&(and)、||(or) 、!(not)
- 模糊查询条件:
- like:一般搭配通配符使用,可以判断字符型或数值型
- 通配符:%任意多个字符,_任意单个字符
- between 变量1 and 变量2 : 判断属性是否在变量1和变量2之间
- in (常量1,常量2,…):判断属性是否等于那几个常量其中的一个
- is nul 和 is not null:判断属性是否为空,=不能判断null属性哦
2.3 排序
排序一般是加在sql语句的末尾,它是特别靠后执行的语句,它的执行顺序在select后面
排序语法:order by 属性名 排序方式
排序方式:DESC(降序) ASC(升序)
2.4 聚合函数
聚合函数是什么?聚合函数就是对某个属性的多条记录做运算的函数
比如,我们对一张员工表求平均工资,此时一个偌大的员工表查出来却只有一条记录,那就是平均工资 12345(瞎编的数),就是把多条记录的某个属性的值经过运算变成一条记录,就叫聚合函数。
- sum() 和 avg()一般用来处理数值型的属性
- max() min() count()可以处理任何类型的属性
2.5 分组
语法:group by 属性名
作用:将选中属性名中值相同的记录划分为一组,比如现在有一个部门表,我们使用了group by 部门后,部门为销售部的是一组,行政部的为一组,这样的逻辑。
注意:使用了group by 语句后,select就只能选择聚合函数和分组用的属性作为我们的列名了,举个例子:
例:当我们用部门作为我们分组的属性时,这时候我们把所有的员工按照部门已经分好了,我们用select来选取需要的属性的时候只能选取部门和一些聚合函数( 像max(工资) count(*)这样的函数)作为我们最后结果的列名。
原因:我个人理解因为当按照部门分好组后,我们应该对这个部门做出操作,比如查询这个部门的平均工资,员工人数等等,如果这时候我们要查某一个员工的姓名,这在逻辑上是不合适的,虽然这样执行不会报错,但它的结果是没有意义的。
三、常见函数
3.1 字符串函数
+ substr(属性名,起始位置) 和 substr(属性名,起始位置,截取个数)
+ replace(str, from str, to str)
+ length()
+ concat(str1, str2) 连接字符串
+ upper(str), lower(str)
+ trim(str)
+ lpad(str,len,padStr) rpad(str,len,padStr)
+ instr(str,substr):获取substr在str第一次出现的索引
3.2 数学函数
+ round(x,d):四舍五入,d代表保留到小数点后第几位
+ mod(n,m)
+ floor:向下取整
+ ceil:向上取整
+ truncate(n):截断到第n位小数
+ round():0-1之间的随机数,取不到1
3.3 日期函数
日期在数据库的使用中是非常重要的,也是非常容易出问题的,下面我们来揭开它神秘的面纱
基本的日期函数:
- now():返回当前系统的日期和时间
- year() month() day() minute() second …
- curdate():返回当前日期
- curtime():返回当前时间
- date_format(date,format):将日期转化为字符串
将format的格式都列出来:
%M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 数字, 4 位
%y 年, 数字, 2 位
%d 月份中的天数, 数字(00……31)
%e 月份中的天数, 数字(0……31)
%m 月, 数字(01……12)
%H 小时(00……23)
%h 小时(01……12)
%I 小时(01……12)
%l 小时(1……12)
%i 分钟, 数字(00……59)
%r 时间,12 小时(hh:mm:ss [AP]M)
%T 时间,24 小时(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM - str_to_date(str,format):将字符串转换为日期格式
- datediff(date1,date2):date1-date2的天数,可以为负
注意:像"2017-02-21"或"17-02-21"这种字符串可以隐式转化成date格式的数据
3.4 其他函数
version 当前数据库服务器的版本
database 当前打开的数据库
user当前用户
password(‘字符’):返回该字符的密码形式
md5(‘字符’):返回该字符的md5加密形式
四、多表连接
准则:当查询的属性涉及到多张表,则必须使用多表连接,此时子查询也不再适用
4.1 内连接
语法:
select 查询列表
from 表1 别名
【inner】 join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;
- 等值连接: 表1.key = 表2.key
- 非等值连接: 表1.key between 表2.key1 and 表2.key2(仅列举一种,形式不限)
- 自连接: 别名1.key1 = 别名2.key2
注意:内连接是取两个表中符合条件j记录的交集(针对记录而不是属性,许多同学错以为是两个表中列的交集,这是不对的,而是行的交集)
4.2 外连接
首先需要注意的是外连接是存在主从关系的,主表的记录会被完整的保留等待后序的筛选
主表与从表之间的关系如上图所示,若在连接时主表中的部分记录与从表无法匹配,则该记录关于从表的属性的值都为null。
select d.department_id,d.department_name,e.*
from departments d LEFT join employees e
ON d.department_id = e.department_id
结果:
可以看到后面几行关于employee的信息都是null,这就是基于上面所说的理论。
外连接分为左外连接left join 和右外连接 right join 它们只是用来声明谁是主表谁是从表而已,原理跟上面说的一样。
五、子查询
含义:
出现在其他语句中的select语句,称为子查询或内查询
外部的查询语句,称为主查询或外查询
子查询的优先级高于外部查询
自己总结了一下规律,发现用子查询的情景都能用连接取做,但是连接的效率太低,所以我们涉及到其他表的数据的时候能用子查询则用子查询。
5.1 分类
- 按结果集分
标量子查询:只包含一行一列,也就是一个值,常伴随> = <这种判断符号进行判断
列子查询:包含一列多行,常用in连接
行子查询:一行多列
表子查询:多行多列,跟在from后面,相当于一个虚表 - 按位置分
select后面:
仅仅支持标量子查询
from后面:
支持表子查询
where或having后面:★
标量子查询(单行) √
列子查询 (多行) √
行子查询
exists后面(相关子查询)
表子查询
5.2 where或having后的子查询
在where或having后面能跟着:1、标量子查询(单行子查询)2、列子查询(多行子查询)3、行子查询(多列多行)
- 标量子查询
案例1:谁的工资比 Abel 高?
#①查询Abel的工资
SELECT salary
FROM employees
WHERE last_name = 'Abel'
#②查询员工的信息,满足 salary>①结果
SELECT *
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name = 'Abel'
);
- 列子查询(多行子查询)
案例1:返回location_id是1400或1700的部门中的所有员工姓名
#①查询location_id是1400或1700的部门编号
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
#②查询员工姓名,要求部门号是①列表中的某一个
SELECT last_name
FROM employees
WHERE department_id =ANY(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
- 行子查询(结果集一行多列或多行多列)
#案例:查询员工编号最小并且工资最高的员工信息
#方式一:行子查询
SELECT *
FROM employees
WHERE (employee_id,salary)=(
SELECT MIN(employee_id),MAX(salary)
FROM employees
);
#方式二:标量子查询
#①查询最小的员工编号
SELECT MIN(employee_id)
FROM employees
#②查询最高工资
SELECT MAX(salary)
FROM employees
#③查询员工信息
SELECT *
FROM employees
WHERE employee_id=(
SELECT MIN(employee_id)
FROM employees
)AND salary=(
SELECT MAX(salary)
FROM employees
);
行子查询一般可以被标量子查询代替,并且标量子查询的使用更加灵活
5.3 select后面的子查询
注意:仅仅支持标量子查询
#案例1:查询每个部门的员工个数
SELECT d.*,(
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.`department_id`
) 个数
FROM departments d;
#案例2:查询员工号=102的部门名
select
(
select department_name
from departments d
where d.department_id = e.department_id
) 部门名
from employees e
where e.employee_id=102
5.4 from后面
将子查询结果充当一张表,要求必须起别名
#案例:查询每个部门的平均工资的工资等级
#①查询每个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
SELECT * FROM job_grades;
#②连接①的结果集和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal
SELECT ag_dep.*,g.`grade_level`
FROM (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;
六、联合查询
联合查询是将多个查询语句的记录合并在一起,用关键字union来连接多个查询语句
语法:查询语句1 union 查询语句2 union 查询语句3 …
作用:当我们需要多个查询的结果时,这样的写法可读性很高
案例1:查询部门编号>90或邮箱包含a的员工信息
SELECT * FROM employees WHERE email LIKE '%a%'
UNION
SELECT * FROM employees WHERE department_id>90;
案例:查询中国用户中男性的信息以及外国用户中年男性的用户信息
SELECT id,cname FROM t_ca WHERE csex='男'
UNION ALL
SELECT t_id,tname FROM t_ua WHERE tGender='male';
注意:
1. 各个语句查询的列数要一样多(硬性要求)
2. 多个查询语句中列的属性最好一致,各个语句查询结果的含义应该是一致的