• 第六十一篇 SQL查询语句


    一、补充(添加数据)

    将一个查询的结果插入到另一张表中

    create table person(name char(10), gender enum('male', 'female') default 'male');
    
    insert into person values('king', 'male'),('jojo', 'male'),('siri', 'female');
    
    create table man(name char(10), gender char(10));
    
    # 将在一个表中查询的结果插入到另一个表中
    # 语法:
    insert into 表名2 select * from 表名1 where 条件;
    # 示例:
    insert into man select * from person where gender = 'male';
    

    二、SQL查询方法

    1.指定字段

    1.1 星号(*)表示所有字段:

    select * from 表名;
    

    1.2 手动指定需要查询的字段:

    select 字段名 from 表名; 
    # 可以用逗号隔开多个字段来查询记录中的多个字段信息
    # 示例:
    select name, gender, salary from emp;
    

    1.3 可以使用四则运算(MySQL5.6版本中可以 +、 -、 * 、/ 、%)

    # 示例:
    select name, (math + english) / 2 as 平均分 from student where english > 100;
    

    1.4 取别名(as)

    # 在字段后面加 as(不加也可以),可以将别名用引号括起来(不用也行)
    # 示例:
    select name as "姓名" from emp where salary > 10000;
    

    1.5 单行函数(lower、upper)

    可以将输出的值小写/大写

    # 示例:
    select upper(name) from emp where salary > 10000;
    

    2.distinct

    去除重复记录,一般放在查询字段的前面

    # 示例:
    select distinct name from emp;
    
    # 当查询字段为*时,仅当查询结果中所有字段全都相同时,才算重复的记录
    select distinct * from emp;
    

    3.聚合函数(又称多行函数/统计函数)

    统计多行返回一个值(由于MySQL5.6版本没有报错,所以当聚合函数得到一个值,但是查询语句中包含有多个值的字段时,将会输出该字段的首个数据)

    # 1.求和   
    sum(字段名)
    
    # 2.平均数
    avg(字段名)
    
    # 3.最大值  
    max(字段名)
    
    # 4.最小值  
    min(字段名)
    
    # 5.个数    
    count(字段名)    # 当指定字段时,如果字段为空不会被计入;字段名称可以使用*代替,可以得到完整的个数
    
    # 这些聚合函数可以用在字段的位置,或是分组的后面   
    # 例如: 查询所有人的平均工资  
    select avg(salary) from emp
    
    # 错误案例1: 查询工资最高的人的姓名 
    select name,max(salary) from emp; 
    # 分析:将默认显示第一个name。因为name有很多行,而max(salary) 只有一行,两列的行数不匹配
    
    # 错误案例2:
    select name from emp where salary = max(salary);
    #逻辑错误,分析:where读取满足条件的一行,max()要先拿到所有数据 才能求最大值,但后面的max函数由于没有数据可读(缺少查询语句),所以无法去求出最大值,因而where也无法拿到条件去前面查询数据
    
    # 结论:where 后面不能使用聚合函数 
    

    4.where

    比较常见的查询过滤方法,通过在where后面接条件来查询想要的数据

    # 语法:
    select 字段名(可以多个或*) from 表名 where 字段名 比较运算符/成员运算符/逻辑运算符 值;
    
    # 1.比较运算符(<、 >、 <=、 >=、 =、 !=)
    # 示例:
    select name from emp where salary < 12000;
    
    # 2.成员运算符(in、not in)
    # 成员运算符后面一般是一个集合
    # 示例:
    select name from emp where salary in (3000, 4000);
    
    # 3.逻辑运算符(and、 or、 not)
    # not 必须放在表达式前面;and和or 放在两个表达式中间
    # 示例:
    select name from emp where not salary = 8000;
    select name from emp where salary = 6000 or salary = 5000  -- 打印工资为6000或工资为5000的姓名;
    
    # 4.模糊查询(like:一般与通配符联用)
    # 4.1 % 表示任意个数的任意字符
    # 示例:
    select * from emp where name like 'k%'  -- 打印姓名首字母为k的信息;
    select * from emp where name like '%k'  -- 打印姓名尾字母为k的信息;
    select * from emp where name like '%k%'  -- 只要姓名中含有k就打印;
    
    # 4.2 _ 表示一个任意字符
    # 示例:
    select * from emp where name like '_k' -- 打印姓名中第二个字母为k的信息;
    

    5.group by

    group是分组的意思,group by是将一个整体按照字段来划分为多个组,进而用来统计按相同属性分组后的其他数据

    # 语法:
    select 字段名 from 表名 group by 字段名;
    # 示例:
    select gender, count(*) from emp group by gender;
    
    # 不规范示例:
    select name,sex,count(*) from emp group by sex;
    # mysql5.6版本及以下,用上述语句查询的name的结果仅显示该分组下的第一个字段值  
    # 5.7版本及以上则直接报错 
    # 5.6也可以手动开启这个功能:我们可以添加 ONLY_FULL_GROUP_BY 到sql_mode中避免这个问题( sql_mode = ONLY_FULL_GROUP_BY )
    # 我们可以用group_concat 将分组之外的字段 做一个拼接 ,但是这是没有意义
    # 如果要查询某个性别下的所有信息 直接使用where 即可  
    
    #结论: 只有出现在了group by 后面得字段才能出现在select的后面
    

    6.having

    用于对分组后的数据进行筛选过滤,与where不同的是,where是从文件读取时的过滤条件,这导致了where无法使用聚合函数(因为数据读取工作都没有完成 不可能统计出数据),having是在分组后进行的过滤条件,所以可以使用聚合函数进行统计数据

    # 语法:
    select 字段名 from 表名 group by 字段名 having 条件(可以使用聚合函数);
    # 示例:
    select count(*) from emp group by deptno having count(name) < 3;
    
    # 也可以在组中再分组(以最后一次分组的字段为准)
    select count(*) from emp group by deptno, job;
    

    7.order by

    用于对记录排序

    # asc是升序,desc是降序
    # 语法:
    select 字段名 from 表名 order by 字段名;(默认是升序)
    
    # 示例:
    select * from emp order by deptno, salary desc;
    

    8.limit

    1.用于限制显示的记录数,用法:limit [start,] count;

    2.start:开始位置

    3.count:显示条数

    4.注意:不指定start 时,则从第一条开始显示

    # 查看前三人
    select *from emp limit 3;
    
    # 查看工资最高的那个人信息
    select *from emp order by salary desc limit 1;
    
    # 指定起始位置
    # 查看id为3-6的人的记录
    select *from emp limit 2,4;  # limit默认从0开始,但我们设置的id都是从1开始,所以0到2有3个数,因此id就是3开始
    
    
    # limit:可用于分页
    # 分页原理:
    # 1.先查询总数据条数 设为a
    # 2.确定每页数量b
    # 3.总页数为c = a / b 
    # 4.如果除不尽则需要加1,例如 10 / 3 正确页数为4
    # 5.查询语句的起始位置为 s = (当前页数 d 减去1)乘以每页数量
    # 6.即  s =  (d - 1) * b
    # 7.语句为:select*from table_name limit s,b
    

    三、多表查询

    # 不存在外键关联的两张表
    
    # 员工表(存在一些不正确的部门id)
    create table emp (id int,name char(10),sex char,dept_id int);
    insert emp values(1,"大黄","m",1);
    insert emp values(2,"老王","m",2);
    insert emp values(3,"老李","w",30);
    
    # 部门表(存在一些没有员工的的部门)
    create table dept (id int,name char(10));
    insert dept values(1,"市场");
    insert dept values(2,"财务");
    insert dept values(3,"行政");
    

    1.笛卡尔积查询

    是两张表相乘的结果,若左边有m条 右边有n条 查询结果为m*n条; 往往包含大量错误数据

    select *from dept,emp;  
    select *from dept,emp where dept.id = dept_id;  
    

    2.链接查询

    2.1 内链接查询

    1.本质上就是笛卡尔积查询

    2.查询出两张表都有匹配关系的记录

    select *from dept,emp where dept.id=emp.dept_id;  
     #where用于筛选数据,而在多多表查询中要筛选的是两边的关系 on用于过滤关联关系
     #而where单独做条件过滤,这样sql看起来可以更清晰明确,当然where依然可以代替on  
    
    select *from dept join emp on dept.id=emp.dept_id;
    inner可以省略
    

    2.2 外链接查询

    2.2.1 左外链接查询

    左表中记录的无论是否有匹配关系都全部显示,右表中仅显示匹配成功的记录

    select *from dept left join emp on dept.id=emp.dept_id;
    

    2.2.2 右外链接查询

    右表中记录的无论是否有匹配关系都全部显示,左表中仅显示匹配成功的记录

    select *from dept right join emp on dept.id=emp.dept_id;
    

    2.2.3 全外链接查询

    1.无论是否匹配成功,两边表中的记录都要全部显示

    2.union 只能用于字段数量相同的两个表 ,会自动去除重复的记录

    3.union all 则保留所有记录

    #mysql 不支持
    select *from dept full join emp on dept.id = emp.dept_id;  
    
    #mysql中可以使用合并查询结果 在所有语句最后写分号
    select *from dept left join emp on dept.id=emp.dept_id
    union
    select *from dept right join emp on dept.id=emp.dept_id;
    

    3.子查询

    1.子查询介绍

    1.当一个查询是另一个查询的条件时,这个查询称之为子查询(内层查询)

    2.当查询需求比较复杂,一次性查询无法得到结果,需要多次查询时,就可以使用子查询

    3.把一个复杂的问题拆分为若干个简单的问题

    4.首先明确子查询就是一个普通的查询,当一个查询需要作为子查询使用时,用括号包裹即可

    #第一步 需要知道财务部的id 
    select id from dept where  name = "财务";
    #第二步 用查询的到的id作为判断条件查询emp
    select name from emp where dept_id = 3;
    
    # 子查询:不能写死,条件或数据源是上一个查询的结果,所以直接写在后面  加上括号就好了
    select name from emp where dept_id = (select id from dept where  name = "财务");
    

    2.in 关键字查询

    "查询平均年龄大于25的部门名称
    1.子查询方式:
    平均年龄大于25的部门id有哪些?
    先要求出每个部门的平年龄! 筛选出平均年龄大于25的部门id
    拿着部门id 去查询部门表查询"
    select name from dept where id in  (select dept_id from emp group by dept_id having avg(age) > 25);
    
    
    "
    2.多表查询方式:
    先把数据拼接到一起 在加以筛选"
    select dept.name from emp inner join dept
    on emp.dept_id = dept.id 
    group by dept.name
    having avg(age) >25;
    

    3.exists关键字查询

    1.exists 后跟子查询,子查询有结果是为True,没有结果时为False

    2.为true时外层执行,为false外层不执行

    # 查看exists的返回结果: 只有 0 和 1
    select * from emp where exists (select *from emp where salary > 1000);
    # ?
    select (exists (select *from emp where salary > 10000));
    
    
    #综合练习:
    "查询每个部门工资最高的员工信息
    先查询每个部门的最高工资
    将查询结果与员工表联合起来
    在加条件判断部门id相同并且 最高工资相同 则显示"
    #一个查询结果也是一个表 既然是表就能链接起来
    select * from emp  inner join  
    (select dept_id, max(salary) m from emp group by dept_id)  t2
    on emp.dept_id = t2.dept_id 
    where emp.salary = t2.m; 
    

    4.三表联查

    create table tsr(id int primary key auto_increment,t_id int,s_id int,
    foreign key(s_id) references stu(id),
    foreign key(t_id) references tea(id));
    
    insert into stu values(null,"张三"),(null,"李四");
    insert into tea values(null,"egon"),(null,"wer");
    insert into tsr values(null,1,1),(null,1,2),(null,2,2);
    
    
    
    #egon老师教过哪些人?
    select *from stu join tea join tsr
    on stu.id = tsr.s_id and tea.id = tsr.t_id
    where tea.name = "egon";
    
    
    'tea表中查得egon的 id 为1
    关系表中查的 123和egon有关系
    学生表中查得 123的名字为abc'
    

    重点

    #综合练习:
    "查询每个部门工资最高的员工信息
    先查询每个部门的最高工资
    将查询结果与员工表联合起来
    在加条件判断部门id相同并且 最高工资相同 则显示"
    
    #一个查询结果也是一个表 既然是表就能链接起来
    select * from emp  inner join  
    (select dept_id, max(salary) m from emp group by dept_id)  t2
    on emp.dept_id = t2.dept_id 
    where emp.salary = t2.m; 
    
  • 相关阅读:
    最易理解的傅里叶分析讲解
    python获取最大、最小值
    机器学习周志华——学习器性能度量
    机器学习周志华——模型评估与选择
    机器学习周志华——机器学习重要会议及期刊
    机器学习周志华——机器学习的应用领域
    机器学习周志华——机器学习的发展
    在github上保存vscode的配置(后续重新安装vscode时,可以十分方便地从github上下载安装这个保存的配置)
    windows 10 macbook air 无声音
    监控 4MM 6MM 8MM 选择
  • 原文地址:https://www.cnblogs.com/itboy-newking/p/11276838.html
Copyright © 2020-2023  润新知