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唯一标识符先进行筛选数据,再分页
相关推荐
云和数据.ChenGuang5 小时前
Django 应用安装脚本 – 如何将应用添加到 INSTALLED_APPS 设置中 原创
数据库·django·sqlite
woshilys6 小时前
sql server 查询对象的修改时间
运维·数据库·sqlserver
Hacker_LaoYi6 小时前
SQL注入的那些面试题总结
数据库·sql
建投数据7 小时前
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
数据库·腾讯云
Hacker_LaoYi8 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀8 小时前
Redis梳理
数据库·redis·缓存
独行soc8 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天8 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺8 小时前
分布式系统架构:服务容错
数据库·架构
独行soc9 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘