• MySql查询进阶


    1.1 as关键字

    用于 给显示结果中字段 或者 表 起别名

    select 别名.字段名 from 表名 as 别名 where 条件语句

    # 对字段起别名
    select id as '编号', name as '大名',age as '年龄' from students;
    # 修改的显示结果中的字段名称不影响表中实际名称;别名只在当前SQL中有效
    
    # 对表名起别名 如果需要通过表名获取字段 别名.字段
    mysql> select s.id,s.name from students as s;
    # select students.id,students.name from students;
    

    as 在 MySQL中可以省略
    select id '编号', name '大名',age '年龄' from students;

    1.2 distinct

    把显示的结果中去除重复的行数据

    select distinct 字段 from 表名

    mysql> select age,height,gender from students;
    +------+--------+--------+
    | age | height | gender |
    +------+--------+--------+
    | 19 | 172.00 | 男 |
    | 88 | 173.00 | 男 |
    | 100 | 160.00 | 女 |
    | 100 | 165.00 | 未知 |
    | 0 | 180.00 | NULL |
    | 0 | NULL | NULL |
    | 0 | NULL | NULL |
    mysql> select distinct age,height,gender from students;
    +------+--------+--------+
    | age | height | gender |
    +------+--------+--------+
    | 19 | 172.00 | 男 |
    | 88 | 173.00 | 男 |
    | 100 | 160.00 | 女 |
    | 100 | 165.00 | 未知 |
    | 0 | 180.00 | NULL |
    | 0 | NULL | NULL |
    

    1.3 where 子句

    应用场景 - 筛选记录中满足条件的数据 如果满足就予以显示。

    # 1 2 3 判断 可以使用其中元素 也可以使用元素对应的位置(从1开始)
    enum ('男','女','中性');
    
    mysql> select * from students where gender = '男';
    mysql> select * from students where gender = 1;
    mysql> select * from students where age >=10 and age <= 50;
    
    # 模糊查询 只知道数据的一部分 查询数据 like 
    # % 匹配 任意个任意字符
    # _ 匹配 1 个任意字符
    mysql> select * from students where name like '张%';
    mysql> select * from students where name like '张_';
    mysql> select * from students where name like '张__';
    
    # 范围查询 
    # 1.连续范围:字段 between 下限 and 上限 [下限, 上限]
    mysql> select * from students where age between 10 and 50;
    
    # 2.不连续范围 字段名 in (值1, 2...)
    mysql> select * from students where age = 19 or age = 29 or age = 39;
    mysql> select * from students where age in (19,29,39);
    
    # 判空 IS NULL 判断非空 IS NOT NULL
    # NULL是一种状态 不能使用 = 判断
    -- select * from students where height = NULL;
    mysql> select * from students where height IS NULL;
    mysql> select * from students where height IS NOT NULL;
    
    

    1.4 排序order by

    应用场景-需要将数据按照一定顺序排列。如竞价 点击量 重要程度。

    select * from 表名 order by 字段名 降序DESC|升序ASC(默认);

    mysql> select * from students order by age ASC;
    mysql> select * from students order by age;
    
    -- 以年龄 降序排序 
    mysql> select * from students order by age DESC;
    
    -- 需要用到多个字段排序: 如果第一个字段数据相等 就按第二个字段
    order by 字段名 排序方式, 字段名2 排序方式,....;
    
    -- 先以年龄升序排序 如果有相等的 使用身高降序排序
    mysql> select * from students order by age asc,height desc;
    

    1.5 分页limit

    应用在数据量大 一次性展示不完 一次给用户展示一页。

    热搜榜 Top 50 order by 热点 降序 分页;

    limit 数据下标=0,数量 # 数据下标默认从0开始 显示数量条信息
    limit 30 == limit 0,30
    
    -- 显示身高最高的前三名
    mysql> select * from students order by height desc limit 0,3;
    mysql> select * from students order by height desc limit 3;
    
    -- 显示身高最高的第四名-第6名
    mysql> select * from students order by height desc limit 3,3;
    
    起始下标 结束下标 100条
    第1页 0 99
    2 100 199
    3 200 299
    n (n-1)*100 100n-1
    ----------------------每页数据条数是 m 个---------——------------
    n limit m*(n-1),m
    

    1.6 聚合函数

    对一组数据进行统计计算 得到一个值。组函数。

    组函数默认对 字段为 NULL 的不统计 一个值 = 组函数(字段名)

    组函数 默认情况下把整个表当做一个组来进行统计计算的

    求和 sum()
    select sum(字段名) from 表名;
    
    计数/统计数量 count()
    常用于统计表中数据行数 select count(*) from 表名;
    
    平均数 avg()
    mysql> select sum(height)/count(height) '平均身高'from students;
    mysql> select avg(height) from students;
    
    最大值 max()
    mysql> select max(height) from students;
    
    最小值 min()
    mysql> select min(age) from students;
    

    ifnull(参数1,参数2) 判断参数1是否为NULL 如果为 NULL 返回参数2;如果不为 NULL 返回参数1

    1.7 分组

    按照1个或者多个字段进行分类,每一类数据在同一个小组中,分别对每个小组进行统计。

    组函数 结合分组使用 统计的不再是整个表 而是每个小组

    -- 分组之后 结果 已经发生的结构上的变化 而不能使用之前的 SQL 看所有数据
    -- select * from students group by gender; # 报错
    
    -- group_concat() 所有成员的某个字段 合并在一行显示
    mysql> select gender,group_concat(height) from students group by gender;
    +--------+----------------------+
    | gender | group_concat(height) |
    +--------+----------------------+
    | NULL | 180.00 |
    | 男 | 172.00,173.00 |
    | 女 | 160.00 |
    | 未知 | 165.00 |
    mysql> select gender,group_concat(name) from students group by gender;
    +--------+-------------------------------+
    | gender | group_concat(name) |
    +--------+-------------------------------+
    | NULL | 张三,张三丰,张三丰了 |
    | 男 | Tom,司马狗剩 |
    | 女 | jerry |
    | 未知 | 老宋 |
    mysql> select gender,group_concat(id,name) from students group by gender;
    mysql> select gender,group_concat(name),group_concat(id) from students group by gender;
    
    -- 组函数 会对分组之后的每个小组分别统计
    mysql> select gender,count(*) from students group by gender;
    +--------+----------+
    | gender | count(*) |
    +--------+----------+
    | NULL | 3 |
    | 男 | 2 |
    | 女 | 1 |
    | 未知 | 1 |
    
    
    -- having 条件 是针对 分组结果进行过滤的 和 where 不能混淆
    mysql> select gender,count(*) from students group by gender
    -> having count(*) < 3;
    
    mysql> select gender,avg(age) from students group by gender
    -> having avg(age) > 80;
    
    
    -- with rollup 在分组结果后新开一行 显示汇总结果
    mysql> select gender,group_concat(name),count(*) from students group by gender with rollup;
    +--------+-----------------------------------------------------+----------+
    | gender | group_concat(name) | count(*) |
    +--------+-----------------------------------------------------+----------+
    | NULL | 张三,张三丰,张三丰了 | 3 |
    | 男 | Tom,司马狗剩 | 2 |
    | 女 | jerry | 1 |
    | 未知 | 老宋 | 1 |
    | NULL | 张三,张三丰,张三丰了,Tom,司马狗剩,jerry,老宋 | 7 | 汇总行
    

    1.8 连接

    如果需要将来自多个表的多个字段拼接在一个结果中显示

    select * from (左表 join 右表 on 连接条件); --on条件用于过滤笛卡尔积(左表每行拼接右表每行)

    # 内连接 inner join / join
    # 取出左表和右表有关联的数据
    mysql> select * from hero join gongfu on hero.gongfuid=gongfu.id;
    +----+-----------+----------+----+--------------+
    | id | name | gongfuid | id | name |
    +----+-----------+----------+----+--------------+
    | 2 | 李白 | 1 | 1 | 吟诗作对 |
    | 1 | 妲己 | 2 | 2 | 魅惑 |
    | 3 | 程咬金 | 3 | 3 | 三板斧 |
    
    # 外连接 outer join 内连接基础上添加额外数据
    # 左外连接 left outer join / left join 内连接基础上添加来自左表的额外数据 右表位置 NULL 填充
    mysql> select * from hero left join gongfu on hero.gongfuid=gongfu.id;
    +----+-----------+----------+------+--------------+
    | id | name | gongfuid | id | name |
    +----+-----------+----------+------+--------------+
    | 2 | 李白 | 1 | 1 | 吟诗作对 |
    | 1 | 妲己 | 2 | 2 | 魅惑 |
    | 3 | 程咬金 | 3 | 3 | 三板斧 |
    | 4 | 公孙离 | 5 | NULL | NULL |
    
    # 右外连接 right outer join / right join内连接基础上添加来自右表的额外数据 左表位置 NULL 填充
    mysql> select * from hero right join gongfu on hero.gongfuid=gongfu.id;
    +------+-----------+----------+----+--------------+
    | id | name | gongfuid | id | name |
    +------+-----------+----------+----+--------------+
    | 1 | 妲己 | 2 | 2 | 魅惑 |
    | 2 | 李白 | 1 | 1 | 吟诗作对 |
    | 3 | 程咬金 | 3 | 3 | 三板斧 |
    | NULL | NULL | NULL | 4 | 沉默 |
    
    -- 以下为数据来源:
    -- 执行下面语句 构造数据表
    create table hero(
    id int unsigned primary key auto_increment,
    name varchar(64) not null,
    gongfuid int unsigned not null
    );
    
    create table gongfu(
    id int unsigned primary key auto_increment,
    name varchar(64) not null
    );
    
    insert into hero (name,gongfuid) values ('妲己',2),('李白',1),('程咬金',3),('公孙离',5);
    insert into gongfu (name) values ('吟诗作对'),('魅惑'),('三板斧'),('沉默');
    

    1.9 自连接

    自关联 self join

    当连接时 左表和右表的数据是来自于同一张表时 - 称为自连接

    由于左表和右表名字一样 所以需要给表起别名。

    左表 as 别名 join 右表 as 别名 on 左表字段 关联 右表字段

    -- 导入 sql 文件
    source /home/python/Desktop/areas.sql;
    
    -- 把areas city join areas pro on city.pid = pro.id当做一个虚表
    mysql> select * from areas city join areas pro on city.pid = pro.id 
    where pro.title = '河南省';
    

    1. 10子查询

    概念: 主查询中嵌套的子查询

    方式:将第一次查询的结果用作第二次查询的范围

    种类: 是根据子查询返回的结果 类型

    ​ 标量 -子查询返回的结果是一行一列(一个值):主要使用聚合函数即可

    ​ 行 - 一行多列

    ​ 列 - 一列多行

    ​ 表 - 多行多列

    -- 标量  求班级中 身高高于平均身高的学生信息
    	1 求出平均身高
    		select avg(height) from students;
    	2 根据平均身高 比较 身高大于平均身高的学习信息
    		select * from students where height > 170;
    
    子查询语句:
    select * from students where height > (select avg(height) from students);
    
    -- 行  求出 班级中身高最高并且年龄最大的同学
    	1 求出最高身高 最大年龄
    	select max(age), max(height) from students;
    	
    	2 根据1步数据去学生表中查询信息
    	mysql> select * from students where age = 101 and height = 180;
    	mysql> select * from students where (age,height) = (101,180);
    
    子查询语句:
    select * from students where (age,height) = (select max(age), max(height) from students);
    
    -- 列  查询出所有使用了技能表中技能的所有英雄
    	1 获取所有的技能 id
    	select id from gongfu;
        +----+
        | id |
        +----+
        |  1 |
        |  2 |
        |  3 |
        |  4 |
    	2 据1步数据去英雄表中查询信息
    	select * from hero where gongfuid in (1,2,3,4);
    
    子查询语句:
    	select * from hero where gongfuid in (select id from gongfu);
    

    保留两位小数的写法round(avg(price),2)

    1.11. 外键约束

    作用:

    ​ 子表: 引用主表字段中数据的表 (外键在子表中)

    ​ 主表: 提供数据给别表使用的

    当对子表中外键字段数据进行更新时 要求新值必须在主表对应字段中存在,如不存在则 更新失败

    如果创建外键失败 1SQL错误 2表中已有数据不满足外键约束 3子表外键字段类型和主表不一样

    创建外键:

    表已经存在:添加外键约束
    	alter table 子表名 add foreign key (子表字段) references 主表名 (主表字段);
    
    创建子表同时添加外键约束
    	create table haha(
      	字段名 类型 约束,
        ....,
        foreign key (字段名) references 主表名(主表字段)
      )
      
    查看外键约束名称
    	show create table hero; 
    	CONSTRAINT `hero_ibfk_1` FOREIGN KEY // hero_ibfk_1就是外键约束名称 用来删除外键约束
    	
    删除外键约束 知道外键约束的名字
    	alter table 表名 drop foreign key 外键约束名;
    

    外键还有一种提法:一对多 和 一对一。

    当一对一时:

    当一对多时:多是子表,一是主表。 一般主表(一)中的一个字段能关联到子表(多)中的多个字段。

    例如: 表一:游戏名 表二:游戏中的英雄名。

    ​ 显然,一款游戏中有多个英雄。所以表一是主表(一),表二是子表(多)。英雄表的每一个字段都由一个外键连接到游戏表中的唯一一款游戏。外键也是在游戏表中。

  • 相关阅读:
    Java各种数据结构实现
    Lintcode答案&笔记
    JavaScript之onclick事件
    CSS3过渡结束监听事件,清除/修改表单元素的一些默认样式
    移动端自动调整根元素字体大小
    手机移动端事件封装
    js 拖拽 鼠标事件,放大镜效果
    CSS 常用属性之 阴影
    CSS常用属性之选择器
    全屏banner及全屏轮播
  • 原文地址:https://www.cnblogs.com/sablier/p/11065329.html
Copyright © 2020-2023  润新知