zoukankan      html  css  js  c++  java
  • Mysql数据查询

    Mysql查询

    数据多次过滤

    条件:from、where、group by、having、distinct、order by、limit => 层层筛选后的结果

    查:
    select [distinct] 字段1 [[as] 别名1],...,字段n [[as] 别名n] from [数据库名.]表名 [条件];
    

    注:一条查询语句,可以拥有多种筛选条件,条件的顺序必须按照上方顺序进行逐步筛选,distinct稍有特殊(书写位置),条件的种类可以不全

    可以缺失,但不能乱序

    单表查询

    distinct 去重

    数据为:
    +------+------+
    | x    | y    |
    +------+------+
    |    1 |    2 |
    |    2 |    3 |
    |    3 |    4 |
    |    1 |    2 |
    +------+------+
    #执行
    select distinct * from t1;
    +------+------+
    | x    | y    |
    +------+------+
    |    1 |    2 |
    |    2 |    3 |
    |    3 |    4 |
    +------+------+
    
    # 总结:distinct对参与查询的所有字段,整体去重(所查的全部字段的值都相同,才认为是重复数据)
    

    常用函数

    拼接:concat() | concat_ws()
    大小写:upper() | lower()
    浮点型操作:ceil() | floor() | round()
    整型:可以直接运算
    

    concat()和concat_ws()

    mysql>: select name as 姓名, concat(area,'-',port) 地址 from emp;  # 上海-浦东
    mysql>: select name as 姓名, concat_ws('-',area,port,dep) 信息 from emp;  # 上海-浦东-教职部
    #concat_ws(),可以在每个字段之间加上第一个字符
    

    upper()和lower()

    select upper(name) 姓名大写,lower(name) 姓名小写 from emp;
    

    ceil(),floor(),round()

    #元数据
    +------+
    | x    |
    +------+
    |  1.5 |
    |  1.2 |
    | 1.51 |
    +------+
    
    #ceil() 向上取整
    mysql> select ceil(x) from t2;
    +---------+
    | ceil(x) |
    +---------+
    |       2 |
    |       2 |
    |       2 |
    +---------+
    
    #floor()向下取整
    mysql> select floor(x) from t2;
    +----------+
    | floor(x) |
    +----------+
    |        1 |
    |        1 |
    |        1 |
    +----------+
    
    #round() 特殊版本的四舍五入 5的时候舍
    mysql> select round(x) from t2;
    +----------+
    | round(x) |
    +----------+
    |        2 |
    |        1 |
    |        2 |
    +----------+
    

    整数

    select x+1 from t1;
    

    where

    常用判断

    比较符合:>  |  <  |  >=  |  <=  |  =  |  !=
    区间符合:between 开始 and 结束 |  in(自定义容器)	| not in
    逻辑符合:and  |  or  |  not
    相似符合:like _|%
    正则符合:regexp 正则语法
    自定义区间:id in (2,3) | id not in (2,3) | id < all(2,3) | id < any(2,3)
    

    案例

    mysql>: select * from emp where salary>5;
    mysql>: select * from emp where id%2=0;
    
    mysql>: select * from emp where salary between 6 and 9;
    
    mysql>: select * from emp where id in(1, 3, 7, 20);
    
    # _o 某o | __o 某某o | _o% 某o* (*是0~n个任意字符) | %o% *o*
    mysql>: select * from emp where name like '%o%';
    mysql>: select * from emp where name like '_o%';  
    mysql>: select * from emp where name like '___o%';
    
    # sql只支持部分正则语法
    mysql>: select * from emp where name regexp '.*d';  # 不支持d代表数字,认为d就是普通字符串
    mysql>: select * from emp where name regexp '.*[0-9]';  # 支持[]语法
    

    all与any:区间修饰条件

    # 语法规则
    # where id in (1, 2, 3) => id是1或2或3
    # where id not in (1, 2, 3) => id不是1,2,3
    # where salary < all(3, 6, 9) => salary必须小于所有情况(小于最小)
    # where salary > all(3, 6, 9) => salary必须大于所有情况(大于最大)
    # where salary < any(3, 6, 9) => salary只要小于一种情况(小于最大)
    # where salary > any(3, 6, 9) => salary只要大于一种情况(大于最小)
    in < > ()
    # 案例
    select * from emp where salary < all(select salary from emp where id>11);
    

    分组group by

    分组与筛选:group by|having

    where和having区别

    1.where在分组之前限定,如果不满足条件,则不参与分组。
      having在分组之后进行限定,如果不满足结果,则不会被查询出来
    2.where后不可以跟聚合函数,having可以进行聚合函数的判断
    

    聚合函数

    max():最大值
    min():最小值
    avg():平均值
    sum():和
    count():记数
    group_concat():组内字段拼接,用来查看组内其他字段
    

    分组查询group by

    配置

    # 修改my.ini配置重启mysql服务
    sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    

    注意

    分组查询的字段只有:分组字段、聚合函数

    having不能使用聚合函数别名

    完整体

    select sex,AVG(math),COUNT(id) from student where math>70 group by sex having count(id) > 2
    

    实验

    #元数据
    +------+------+
    | z1   | z2   |
    +------+------+
    |    1 | zx   |
    |    2 | zy   |
    |    9 | zx   |
    |    5 | zy   |
    |    6 | zx   |
    |    7 | zy   |
    +------+------+
    #执行
    select z2,avg(z1) from t3 group by z2;
    +------+---------+
    | z2   | avg(z1) |
    +------+---------+
    | zx   |  5.3333 |
    | zy   |  4.6667 |
    +------+---------+
    

    联合分组

    简单来说就是对多个字段分组
    
    #执行
    select z1,z2 from t3 group by z1,z2;
    +------+------+
    | z1   | z2   |
    +------+------+
    |    1 | zx   |
    |    2 | zy   |
    |    5 | zy   |
    |    6 | zx   |
    |    7 | zy   |
    |    9 | zx   |
    +------+------+
    

    排序

    排序规则

    # order by 主排序字段 [asc|desc], 次排序字段1 [asc|desc], ...次排序字段n [asc|desc]
    

    未分组状态下

    mysql>: select * from emp;
    
    # 按年龄升序
    mysql>: select * from emp order by age asc;
    # 按薪资降序
    mysql>: select * from emp order by salary desc;
    
    # 按薪资降序,如果相同,再按年龄降序
    mysql>: select * from emp order by salary desc, age desc;
    # 按龄降序,如果相同,再按薪资降序
    mysql>: select * from emp order by age desc, salary desc;
    

    分组状态下

    mysql>:
    select 
    	dep 部门,
    	group_concat(name) 成员,
    	max(salary) 最高薪资,
    	min(salary) 最低薪资,
    	avg(salary) 平均薪资,
    	sum(salary) 总薪资,
    	count(gender) 人数
    from emp group by dep;
    
    # 最高薪资降序
    mysql:
    select 
    	dep 部门,
    	group_concat(name) 成员,
    	max(salary) 最高薪资,
    	min(salary) 最低薪资,
    	avg(salary) 平均薪资,
    	sum(salary) 总薪资,
    	count(gender) 人数
    from emp group by dep
    order by 最高薪资 desc;
    

    分页limit

    # 语法:limit 条数  |  limit 偏移量,条数
    
    #元数据
    +------+------+
    | z1   | z2   |
    +------+------+
    |    1 | zx   |
    |    2 | zy   |
    |    9 | zx   |
    |    5 | zy   |
    |    6 | zx   |
    |    7 | zy   |
    +------+------+
    #执行
    select * from t3 limit 1;
    +------+------+
    | z1   | z2   |
    +------+------+
    |    1 | zx   |
    +------+------+
    
    #执行
    select * from t3 limit 2,2;
    +------+------+
    | z1   | z2   |
    +------+------+
    |    9 | zx   |
    |    5 | zy   |
    +------+------+
    

    多表查询

    分类

    1.内连接

    2.左连接

    3.右连接

    4.全连接

    from 左表 inner|left|right join 右表 on 两个表之间的关联条件 
    inner:都是有用的
    left:左边全有
    right:右边全有
    
    全连:left union right 有用没用都有
    

    笛卡尔积

    笛卡尔积是数据库多表连接的基础,它会列出所有的组合,多表查询其实就是对笛卡尔积进行过滤留下有用的数据
    1 2 3和z x y的笛卡尔积
    1 z 1 x 1 y
    2 z 2 x 2 y 
    3 z 3 x 3 y
    
    select * from z1,z2
    

    一对一和一对多

    元数据

    +------+----------+
    | id   | name     |
    +------+----------+
    |    1 | 教室_1   |
    |    2 | 教室_2   |
    |    3 | 教室_3   |
    |    4 | NULL     |
    | NULL | NULL     |
    +------+----------+
    
    +------+------+
    | id   | name |
    +------+------+
    |    1 | zx   |
    |    2 | wl   |
    |    3 | zy   |
    |    1 | zxy  |
    |    2 | fd   |
    |    3 | hj   |
    |    4 | ds   |
    |    1 | NULL |
    | NULL | NULL |
    +------+------+
    

    内连接

    找两张表共有的部分,相当于利用条件从笛卡尔积结果中筛选出了正确的结果

    # 关键字:inner join on
    # 语法:from A表 inner join B表 on A表.关联字段=B表.关联字段
    可以简写为join
    #执行
     select * from class join student on class.id=student.id;
    +------+----------+------+------+
    | id   | name     | id   | name |
    +------+----------+------+------+
    |    1 | 教室_1   |    1 | zx   |
    |    2 | 教室_2   |    2 | wl   |
    |    3 | 教室_3   |    3 | zy   |
    |    1 | 教室_1   |    1 | zxy  |
    |    2 | 教室_2   |    2 | fd   |
    |    3 | 教室_3   |    3 | hj   |
    |    4 | NULL     |    4 | ds   |
    |    1 | 教室_1   |    1 | NULL |
    +------+----------+------+------+
    
    # 总结:只保留两个表有关联的数据
    

    左连接

    优先显示左表全部记录

    # 关键字:left join on
    # 语法:from 左表 left join 右表 on 左表.关联字段=右表.关联字段
    
    #执行
    select class.id,class.name,student.name from class left join student on class.id=student.id;
    +------+----------+------+
    | id   | name     | name |
    +------+----------+------+
    |    1 | 教室_1   | zx   |
    |    2 | 教室_2   | wl   |
    |    3 | 教室_3   | zy   |
    |    1 | 教室_1   | zxy  |
    |    2 | 教室_2   | fd   |
    |    3 | 教室_3   | hj   |
    |    4 | NULL     | ds   |
    |    1 | 教室_1   | NULL |
    | NULL | NULL     | NULL |
    +------+----------+------+
    # 总结:保留左表的全部数据,右表有对应数据直接连表显示,没有对应关系空填充
    

    右连接

    优先显示右表全部记录

    # 关键字:right join on
    # 语法:from A表 right join B表 on A表.关联字段=B表关联字段
    
    #执行
    select class.id,student.name,class.name from class right join student on class.id=student.id;
    +------+------+----------+
    | id   | name | name     |
    +------+------+----------+
    |    1 | zx   | 教室_1   |
    |    1 | zxy  | 教室_1   |
    |    1 | NULL | 教室_1   |
    |    2 | wl   | 教室_2   |
    |    2 | fd   | 教室_2   |
    |    3 | zy   | 教室_3   |
    |    3 | hj   | 教室_3   |
    |    4 | ds   | NULL     |
    | NULL | NULL | NULL     |
    +------+------+----------+
    # 总结:保留右表的全部数据,左表有对应数据直接连表显示,没有对应关系空填充
    

    左右可以相互转化

    更换一下左右表的位置,相对应更换左右连接关键字,结果相同

    全连接

    全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果

    #执行
    select class.id,student.name,class.name from class left join student on class.id=student.id
    UNION
    select class.id,student.name,class.name from class right join student on class.id=student.id
    order by id;
    
    +------+------+----------+
    | id   | name | name     |
    +------+------+----------+
    | NULL | NULL | NULL     |
    |    1 | zxy  | 教室_1   |
    |    1 | NULL | 教室_1   |
    |    1 | zx   | 教室_1   |
    |    2 | fd   | 教室_2   |
    |    2 | wl   | 教室_2   |
    |    3 | hj   | 教室_3   |
    |    3 | zy   | 教室_3   |
    |    4 | ds   | NULL     |
    +------+------+----------+
    # 总结:左表右表数据都被保留,彼此有对应关系正常显示,彼此没有对应关系均空填充对方
    # 注意 union与union all的区别:union会去掉相同的纪录
    

    多对多

    相当于在一对多的基础上,多建立一次连接

    ##源数据
    
    #人物表
    zx
    +----+------+
    | id | name |
    +----+------+
    |  1 | zx   |
    |  2 | wl   |
    |  3 | zy   |
    |  4 | zxy  |
    +----+------+
    
    #关系表
    zx_zy
    +----+-------+-------+
    | id | zx_id | zy_id |
    +----+-------+-------+
    |  1 |     1 |     1 |
    |  2 |     1 |     3 |
    |  3 |     2 |     2 |
    |  4 |     2 |     4 |
    |  5 |     3 |     1 |
    |  6 |     3 |     3 |
    |  7 |     4 |     5 |
    |  8 |     4 |     2 |
    |  9 |     4 |     3 |
    +----+-------+-------+
    
    #技能表
    zy
    +----+-----------+
    | id | name      |
    +----+-----------+
    |  1 | 吃饭      |
    |  2 | 睡觉      |
    |  3 | 打代码    |
    |  4 | 写作业    |
    |  5 | 上厕所    |
    +----+-----------+
    

    查询1

    #执行
    以关系表为中心,进行两次左连接
    select zx_zy.id,zx.name,zy.name from zx_zy LEFT JOIN zx on zx.id=zx_zy.zx_id LEFT JOIN zy on zy.id=zx_zy.zy_id
    
    +----+------+-----------+
    | id | name | name      |
    +----+------+-----------+
    |  1 | zx   | 吃饭      |
    |  2 | zx   | 打代码    |
    |  3 | wl   | 睡觉      |
    |  4 | wl   | 写作业    |
    |  5 | zy   | 吃饭      |
    |  6 | zy   | 打代码    |
    |  7 | zxy  | 上厕所    |
    |  8 | zxy  | 睡觉      |
    |  9 | zxy  | 打代码    |
    +----+------+-----------+
    

    查询2

    #执行
    任意表,进行两次内连接
    select zx_zy.id,zx.name,zy.name from zx join zx_zy on zx_zy.zx_id=zx.id join zy on zx_zy.zy_id=zy.id
    +----+------+-----------+
    | id | name | name      |
    +----+------+-----------+
    |  1 | zx   | 吃饭      |
    |  2 | zx   | 打代码    |
    |  3 | wl   | 睡觉      |
    |  4 | wl   | 写作业    |
    |  5 | zy   | 吃饭      |
    |  6 | zy   | 打代码    |
    |  7 | zxy  | 上厕所    |
    |  8 | zxy  | 睡觉      |
    |  9 | zxy  | 打代码    |
    +----+------+-----------+
    

    子查询

    简单来说就是一个查询的数据当做另一个查询的查询条件

    要注意的是子查询的数据一般有好多,一般用in

    # 增:insert into 表 select子查询
    # 删:delete from 表 条件是select子查询(表不能与delete表相同)
    # 查:select 字段 from 表 条件是select子查询
    # 改:update 表 set 字段=值 条件是select子查询(表不能与update表相同)
    

    简单案例-子查询

    ##元数据
    t1
    +------+------+
    | x    | y    |
    +------+------+
    |    1 |    2 |
    |    2 |    3 |
    |    3 |    4 |
    |    1 |    2 |
    +------+------+
    
    t3
    +------+------+
    | z1   | z2   |
    +------+------+
    |    1 | zx   |
    |    2 | zy   |
    |    9 | zx   |
    |    5 | zy   |
    |    6 | zx   |
    |    7 | zy   |
    +------+------+
    ##需求根据t1的x,删除t3,与t1相同的z1数据
    
    #执行
    select * from t3;
    +------+------+
    | z1   | z2   |
    +------+------+
    |    9 | zx   |
    |    5 | zy   |
    |    6 | zx   |
    |    7 | zy   |
    +------+------+
    
  • 相关阅读:
    C到C++的升级
    设计模式分类
    对模式的十大误解
    MAC帧和IP包的分析
    python之路—从入门到放弃
    选课系统
    Scrapy框架详解
    爬虫系列
    Python从入门到断气
    常用模块
  • 原文地址:https://www.cnblogs.com/zx125/p/11580301.html
Copyright © 2011-2022 走看看