10.数据库查询操作(聚合函数+不同连接+LIke模糊查询+limit分页)

查询操作

文章目录

++MySQL官网++

一、SQL查询语法

查询产生一个虚拟表,看到的是表形式显示的结果,但结果并不真正存储,每次执行查询只是现从数据表中提取数据,并按照表的形式显示出来。

1.基本结构

sql 复制代码
SELECT
    #查询字段
    [ALL | DISTINCT | DISTINCTROW ]
    select_expr [, select_expr] ...
    [into_option]
    [FROM table_references]    
    #查询条件
    [WHERE where_condition]
    #分组
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
    #对分组数据进行筛选
    [HAVING where_condition]   
    #排序: desc降序, 默认asc升序
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    #分页
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]

2.select子句

使用以下几种方式指定字段列表:

字段列表 说明
* 字段列表为数据源的全部字段
表名.* 多表查询时,指定某个表的全部字段
字段列表 指定所需要显示的列
sql 复制代码
select * from tb_name #查询表中全部字段
select col_name from tb_name; #查询表中个别字段数据
select tb_name.col_name from tb_name;#多表查询时,字段前加入表名

3.where子句

where条件语句;后面跟着筛选数据的条件

条件表达式: 条件形式like模糊查询
关键字 解释
比较运算符 单一条件过滤
逻辑运算符 组合多个条件查询
BETWEEN AND 在两数之间
NOT BETWEEN AND 不在两数之间
IN <值表> 是否在特定的集合里(枚举)
NOT IN <值表> 与上面相反
LIKE concat() - 是否匹配于一个模式 - 拼接字符串
IS NULL 为空的
IS NOT NULL 不为空的
Binary 区分大小写
  1. 比较运算符

    =(等于)、>(大于)、>=(大于等于)、<(小于)、<=(小于等于)、<>(不等于)、!=(不等于)

    sql 复制代码
    #举例: 查询条件薪资大于9000的员工
    select * from employee where salary>9000;
  2. 逻辑运算符

    逻辑与(and)、逻辑或(or)以及逻辑非(not),其中逻辑非(not)为单目运算符。

    sql 复制代码
    #查询条件: 查询年龄18以上工资大于9000的员工
    select * from employee where age>18 and salary>9000;
  3. IS NULL运算符

    is NULL用于判断表达式的值是否为空值NULL(is not 恰恰相反)

    sql 复制代码
    #查询地址为空的员工姓名
    SELECT emp_name As 姓名, address  AS 地址 
    FROM EMPLOYEE WHERE address IS NULL;
  4. BETWEEN AND

    把某一字段中内容在特定范围内的记录查询出来

    sql 复制代码
    #查询年龄在18~50的员工
    select * from employee where age between 18 and 50;
  5. IN

    sql 复制代码
    #查询年龄为18,30和50的员工,满足任意1个年龄即查询
    select * from employee where age in(18,30,50);
  6. 模糊查询 like(重点难点模糊点)

    like运算符用于判断一个字符串是否与给定的模式相匹配;(like concat(arg0,arg1....)拼接字符串)

    通配符 含义
    % 指定位置有零个或多个字符
    _ 指定位置有1个
    sql 复制代码
    #查询首字为张的姓名的员工
    SELECT * FROM EMPLOYEE WHERE emp_name  LIKE  '张%';
    #查询员工姓名第二个字是牛的员工信息
    SELECT * FROM EMPLOYEE WHERE emp_name  LIKE  '_牛%';
    -- 查询员工中姓名第二字是"子"的员工
    SELECT * from employee WHERE emp_name LIKE CONCAT('_','子','%');
    SELECT * from employee WHERE emp_name  LIKE '_子%';

    BINARY运算符: 区分大小写

    默认情况,模糊查询不区分大小写,可以添加BINARY关键字让MySQL执行区分大小写的比较

    sql 复制代码
    SELECT * FROM emp WHERE emp_name  LIKE BINARY '%tom%';

二、 聚合函数

min(),max(),sum(),avg(),count()

函数 介绍
SUM() 求总和,只适用于数值类型字段,如果是字符串类型不会报错会返回0,会自动过滤空值
AVG() 求平均值,只适用于数值类型字段,字符串类型不会报错会返回0,会自动过滤空值
MAX() 求最大值,适用于数值类型、字符串类型和日期时间类型字段
MIN() 求最小值,适用于数值类型、字符串类型和日期时间类型字段
COUNT() 用于计算查询结果集中的数据共有多少条
sql 复制代码
-- 查询员工的最低工资是多少
SELECT MIN(salary) FROM employee;
-- 查询员工的最大年龄
SELECT MAX(age) from employee;
-- 查询工资总和
SELECT SUM(salary) from employee;
-- 统计员工人数
SELECT COUNT(emp_id) from employee;
-- 统计员工平均工资
SELECT AVG(salary) from employee;

三.排序,分组,分组筛选

  1. group by

    sql 复制代码
    -- 单列分组
    -- 统计每个部门人数
    SELECT dept_id,COUNT(emp_id) AS 人数 from employee WHERE dept_id is NOT NULL GROUP BY dept_id;
    -- 多列分组
    -- 统计每个部门不同学历的员工有多少人,该怎么办?
    SELECT dep_id AS 部门编号,degree AS 学历, 
        count(*) AS 人数
    FROM EMPLOYEE
    GROUP BY dep_id,degree
    ORDER BY dep_id 
  2. order by col_name [desc | asc]

    排序: 默认asc升序, desc降序

    sql 复制代码
    -- 统计每个部门人数,根据部门人数进行升序排序
    SELECT dept_id,COUNT(emp_id) AS 人数 from employee WHERE dept_id is NOT NULL GROUP BY dept_id ORDER BY COUNT(emp_id);
  3. HAVING

    对分组后的数据进行排序,后面可以跟聚合函数

    sql 复制代码
    -- 统计每个部门人数,根据部门人数进行升序排序,并筛选部门人数大于1的部门
    SELECT dept_id,COUNT(emp_id) AS 人数 from employee WHERE dept_id is NOT NULL GROUP BY dept_id HAVING COUNT(emp_id)>1 ORDER BY COUNT(emp_id);

    WHERE和HAVING的区别?

    1. WHERE子句从数据源中去掉不符合其搜索条件的数据,跟在表名后面,后面不跟聚合函数
    2. HAVING子句去掉不符合其组搜索条件的各组数据行(对分组后的数据进行筛选)
sql 复制代码
-- 完整的sql语句
select dept_id, count(*) from employee 
where dept_id is not null -- 对所有数据进行筛选,不能使用聚合函数,筛选id不为空的数据,第一道筛选数据
GROUP BY dept_id   -- 对where筛选后的数据进行分组
having count(*)>2  -- 对分组后的数据进行再筛选第二道
order by  dept_id desc; -- 对数据根据id进行降序排序

四.连接查询

1、 SQL连接分类:

  • inner连接(内连接)inner join...on

    组合多表记录,返回关联字段相符的记录(交集部分)

  • outer连接(外连接)left | right join...on

    • left(左外连接,简称为左连接)
    • right(右外连接,简称为右连接)
  • cross连接(交叉连接)across join...on

1)inner jon内连接

合并具有同一列的两个以上的表的行,结果集中 包含一个表与另一个表 匹配的行(*<u>**显示都符合二者条件的记录***)

合并具有共同字段的记录,没有共同字段的不显示记录 ;(比如说: employee有员工没有归属某个部门,则没有对应的部门id,则内连接不显示此员工的记录数据)

sql 复制代码
-- 内连接: 返回符合交集的记录,e是employee表另起名
SELECT * from employee e 
INNER JOIN dept d
on e.dept_id=d.dept_id;
2)left join

左表(a_table)的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。

sql 复制代码
-- 左外连接
SELECT * from employee e 
LEFT JOIN dept d
ON e.dept_id=d.dept_id;

注意: 左表employee显示全部数据右表dept没有符和条件(二者dept_id相等)的显示为空null

3)right join

左表e只会显示符合搜索条件的记录,而右表d的记录将会全部表示出来。左表记录不足的地方均为NULL。

sql 复制代码
-- 右连接
SELECT * from employee e 
RIGHT JOIN dept d
ON e.dept_id=d.dept_id;

注意: e表没有dept_id属性值的记录显示为空

4)cross join

多表都符合条件显示记录,类似内连接

sql 复制代码
SELECT * from employee e 
CROSS JOIN dept d 
ON e.dept_id=d.dept_id;
-- 等价于
select * from employee e,dept d where e.dept_id=d.id;
select * from employee e INNER JOIN dept d on e.dept_id=d.id;

五、子查询

0.定义:

实质就是>>嵌套查询语句

  • 子查询的 SELECT 查询总是使用圆括号括起来。
  • 子查询可以嵌套在外部 SELECT、INSERT、UPDATE 或 DELETE 语句的 WHERE 或 HAVING 子句内,或者其它子查询中。
  • 根据可用内存和查询中其它表达式的复杂程度不同,嵌套限制也有所不同,嵌套到 32 层。
sql 复制代码
-- 子查询: 查询工资大于平均工资的员工姓名
SELECT emp_name from employee WHERE salary>(SELECT AVG(salary) FROM employee);

1.多行比较操作符

操作符 含义
IN 等于列表中的任意一个
ANY 需要和单行比较操作符一起使用,和子查询返回的某一个值比较
ALL 需要和单行比较操作符一起使用,和子查询返回的所有值比较
SOME 实际上是ANY的别名,作用相同,一般常使用ANY

2.子查询可出现的位置

位置 类型 说明
select后面: 仅仅支持标量子查询 作为一个字段值
from后面: 支持表子查询 作为一个临时表
where或having后面: 支持标量子查询(单行)、列子查询(多行)、行子查询 作为过滤条件
exists后面(也被称为'相关子查询') 支持表子查询 判断条件是否存在

3.SQL语句举例:

sql 复制代码
-- 查询等于任意部门最低工资的员工记录(in)
select * from employee where salary in (select min(salary) from employee GROUP BY dept_id);
-- 查询大于任意一个部门最低工资的员工信息
select * from employee where salary>any (select min(salary) from employee GROUP BY dept_id);
-- 大于所有部门最低工资的员工信息
select * from employee where salary>all (select min(salary) from employee GROUP BY dept_id);
-- 没有员工的部门信息,SELECT * FROM employee e WHERE d.dept_id=e.dept_id查询有部门的员工记录,不存在查询部门信息(not exists)
SELECT * FROM dept d
WHERE  NOT EXISTS(SELECT * FROM employee e WHERE d.dept_id=e.dept_id);
-- 查询有员工的部门(exists)
select * from dept d where EXISTS (select * from employee e where d.dept_id=e.dept_id );

六. MySQL分页LIMIT(重点)

sql 复制代码
-- 格式: 第一个数字>>起始行数,第二个数字>>展现记录行数
select字段列表 from数据源 limit [start,]length;
-- 分页功能
-- 限制查询limit
-- 查询前5条数据
SELECT * from employee LIMIT 5;
-- 查询前五条后面的五条数据(6~10)
SELECT * from employee LIMIT 5,5;
-- 也可以通过id唯一标识符先进行筛选数据,再分页

d where EXISTS (select * from employee e where d.dept_id=e.dept_id );

## 六. MySQL分页`LIMIT`(重点)

~~~sql
-- 格式: 第一个数字>>起始行数,第二个数字>>展现记录行数
select字段列表 from数据源 limit [start,]length;
-- 分页功能
-- 限制查询limit
-- 查询前5条数据
SELECT * from employee LIMIT 5;
-- 查询前五条后面的五条数据(6~10)
SELECT * from employee LIMIT 5,5;
-- 也可以通过id唯一标识符先进行筛选数据,再分页
相关推荐
兩尛1 小时前
订单状态定时处理、来单提醒和客户催单(day10)
java·前端·数据库
web2u1 小时前
MySQL 中如何进行 SQL 调优?
java·数据库·后端·sql·mysql·缓存
Elastic 中国社区官方博客2 小时前
使用 Elasticsearch 导航检索增强生成图表
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
小金的学习笔记2 小时前
RedisTemplate和Redisson的使用和区别
数据库·redis·缓存
新知图书3 小时前
MySQL用户授权、收回权限与查看权限
数据库·mysql·安全
文城5213 小时前
Mysql存储过程(学习自用)
数据库·学习·mysql
沉默的煎蛋3 小时前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
呼啦啦啦啦啦啦啦啦3 小时前
【Redis】事务
数据库·redis·缓存
HaoHao_0103 小时前
AWS Serverless Application Repository
服务器·数据库·云计算·aws·云服务器
C语言扫地僧3 小时前
MySQL 事务及MVCC机制详解
数据库·mysql