MySQL-查询篇(超详细)

前言

本篇文章主要是给已经有了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开始一直执行到末尾,它的顺序是这样的。

  1. 先看from后面的表,知道在哪个容器(表)中查找我们需要的记录。
  2. 在用where中的筛选条件用来对容器中的记录进行过滤
  3. 最后再选择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. 多个查询语句中列的属性最好一致,各个语句查询结果的含义应该是一致的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值