Mysql总结

作者: 元宝2020 | 来源:发表于2020-08-31 16:08 被阅读0次

    最近又重新复习了一遍SQL的基础和进阶知识,SQL可以很基础也可以很复杂,写一篇总结来梳理自己的知识脉络

    SQL是结构化查询语言,是一种用来操作RDBMS的数据库语言,当前关系型数据库都支持使用SQL语言进行操作,也就是说可以通过 SQL 操作 oracle,sql server,mysql,sqlite 等等所有的关系型的数据库。

    SQL语句主要分为:

    DQL:数据查询语言,用于对数据进行查询,如select

    DML:数据操作语言,对数据进行增加、修改、删除,如insert、udpate、delete

    TPL:事务处理语言,对事务进行处理,包括begin transaction、commit、rollback

    DCL:数据控制语言,进行授权与权限回收,如grant、revoke

    DDL:数据定义语言,进行数据库、表的管理等,如create、drop

    CCL:指针控制语言,通过控制指针完成表的操作,如declare cursor

    数据分析必须熟练编写DQL、DML,能够编写DDL完成数据库、表的操作,其它语言如TPL、DCL、CCL了解即可。


    在实际操作过程中,我使用的是MYSQL,MySQL使用标准的SQL数据语言形式,同时开源免费,适用范围广。开启MYSQL可以用电脑的终端,也可以搭载可视化软件(navicat或mysqlworkbench)。

    一个数据库就是一个完整的业务单元,可以包含多张表,数据被存储在表中。在表中为了更加准确的存储数据,保证数据的正确有效,可以在创建表的时候,为表添加一些强制性的验证,包括数据字段的类型、约束

    MySQL支持所有标准的SQL数据类型,主要分3类:

        ·数值类型

        ·字符串类型

        ·时间日期类型

    可以参考这篇文章-https://blog.csdn.net/anxpp/article/details/51284106

    约束 需要了解:

    ·主键primary key:物理上存储的顺序

    ·非空not null:此字段不允许填写空值

    ·惟一unique:此字段的值不允许重复

    ·默认default:当不填写此值时会使用默认值,如果填写时以填写为准

    ·外键foreign key:对关系字段进行约束,当为关系字段填写值时,会到关联的表中查询此值是否存在,如果存在则填写成功,如果不存在则填写失败并抛出异常。


    数据库的操作

    -- 连接数据库

    mysql -uroot -p (输入密码)

    -- 退出数据库

    exit/quit 

    -- 查看所有数据库

    show databases;

    -- 查看当前使用的数据库;

    select database();

    -- 创建数据库

    create database 数据库名 charset=utf8;

    --使用数据库

    use  数据库名;

    -- 删除数据库

    drop database 数据库名;

    数据表的操作

    -- 查看当前数据库所有表

    show tables;

    -- 查看表结构

    desc 表名;

    -- 创建表

    create table 表名(字段 类型 约束,字段 类型 约束,···);

    create table user_info (

    id int unsigned primary key auto_increment not null,

    name varchar(20) not null

    );

    -- 查看建表语句

    show create table 表名;

     -- 删除表

    drop table 表名;

    表中字段的操作

    -- 修改字段名 重命名

    alter table 表名 change 原列名 新列名 类型及约束;

    alter table user_info change id user_id varchar(20) not null;

    -- 修改字段 不重命名

    alter table 表名 modify 列名 类型及约束;

    -- 添加字段 

    alter table 表名 add 列名 类型;

    -- 删除字段 

    alter table 表名 drop 列名;

    数据的操作 增删改查(crud)

    -- 增加记录

    全列插入 insert into 表名 values(...) 如 insert into classes values(1,'zhangsan');

    部分插入 insert into 表名(列1,...) values(值1,...) 如  insert into classes(name) values('zhangsan');

    多行插入 insert into students values(0,'老刘',40,160,'男',003),(0,'老王',20,180,default,003);

    注意:主键字段 可以用 0、null、default 来占位

    -- 删除记录

    物理删除 delete from 表名 where 条件 

    逻辑删除 即用一个字段来表示这条信息已被删除 

    alter table students add is_delete bit default 0; 

    -- 修改记录

    update 表名 set 列1=值1,列2=值2 ··· where 条件;

    全部修改 update students set gender='保密'

    部分按条件修改 update students set gender='女' where name='huahua'

    按条件修改多个值 update students set gender='男' where cls_id=3;

    -- 查询记录

    全部查询 select * from 表名;

    条件查询 select * from 表名 where 条件;

    查询指定列 select 列名 from 表名 ;

    用AS给字段起别名 select 字段[as 别名] , 字段[as 别名] from 表名

    ***  高级查询语句

    条件查询:使用where子句对表中的数据筛选,结果为true的行会出现在结果集中

    where后面支持多种运算符,进行条件的处理

    1、比较运算符(大于小于等于不等于···)

    2、逻辑运算符(and\or\not)

    3、模糊查询(like:%表示任意多个任意字符, _表示一个任意字符)

    4、范围查询(in、 between··· and···)

    5、空判断(is null、is  not null)

    聚合函数

    1、总数 count(列)不会统计null值记录

    count(*)=count(1) ,结果是相同的,count(列) 不会统计null值记录

    2、最大值 max(列)

    3、最小值 min(列)

    4、求和 sum(列)

    5、求平均值 avg(列)

    分组查询:

    1、group by

    2、group by + group_concat() 

    group_concat(字段名)可以作为一个输出字段来使用

    select gender,group_concat(name) from students group by gender;

    +--------+-----------------------------------------------------------+| 

    gender | group_concat(name) |

    +--------+-----------------------------------------------------------+| 

    男 | 彭于晏,刘德华,周杰伦,程坤,郭靖 || 

    女 | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 || 

    中性 | 金星 || 保密 | 凤姐 |

    +--------+-----------------------------------------------------------+

    3、group by + 集合函数

    4、group by + having 用来分组查询后指定一些条件来输出查询结果

    5、 group by + with rollup 在最后新增一行,来记录当前列里所有记录的总和

    select gender,count(*) from students group by gender with rollup;

    +--------+----------+

    | gender | count(*) |

    +--------+----------+

    | 男    |        5 |

    | 女    |        7 |

    | 中性  |        1 |

    | 保密  |        1 |

    | NULL  |      14 |

    +--------+----------+

    分页查询:

    limit: select * from 表名 limit start,count 从start开始,获取count条数据

    连接查询:

    三种连接查询

    子查询:在一个 select 语句中,嵌入了另外一个 select 语句, 那么被嵌入的 select 语句称之为子查询语句

    子查询分为三类:

    1、标量子查询: 子查询返回的结果是一个数据(一行一列)

    如 查询大于平均年龄的学生

    2、列子查询: 返回的结果是一列(一列多行)

    如 查询所有学生在班的所有班级名字

    3、行子查询: 返回的结果是一行(一行多列)

    如 查询年龄最大,身高最高的学生具体信息

    要感慨一句,子查询可以很复杂,绕人,但是有时候也很好用。。。。


    数据查询的执行顺序

    from-where-groupby-having-select-orderby-limit

    1、from首先从哪张表取数

    2、where筛选条件,不是所有的数据都要

    3、groupby 做一个分组聚合

    4、having 分组聚合后的结果也并不是都要,满足条件的才要

    5、select  选择需要的指定字段

    6、orderby 排序

    7、limit 限制显示数量

    举个例子:从订单表中查询出过去一年内,购买10次以上的用户名单,展示前10名的姓名、购物金额

    select 姓名、sum(price) as 购物金额

    from 订单表

    where 时间=过去一年内

    group by 用户ID

    having count(*)>10

    order by 购物金额 desc

    limit 10

    *having后面可以接聚合函数,但是where后不能接聚合函数,因为执行顺序的原因,where执行时还没有完成分组聚合。


    时间函数

    --获取当前时间

    select now() 执行开始时的系统时间

    select sysdate() 在函数执行时动态得到值

    -- 获取年月日 

    select current_date()

    -- 获取时分秒

    select current_time()

    -- 转换字符串为日期格式

    select str_to_date(时间字符串,字符串日期格式)

    select str_to_date('08/09/08' , '%m/%d/%y'); -- 2008-08-09

    -- 转换日期为字符串格式

    select date_format(now(),'%Y-%M-%d %H')

    -- 提取时间的函数

    常用的year/month/time/day/week/minute/hour/quarter````

    dayofyear,dayofmonth,dayofweek,dayofmonth,yearweek```

    -- 日期的运算

    减法 date_sub(日期 ,要减少偏移的间隔)

    select date_sub('1998-01-01 00:00:00', interval 1 day); --- 1997-12-31 00:00:00

    加法 date_add(date,INTERVAL expr type)

    select date_add('1998-01-01 00:00:00', interval 1 day); --- 1998-1-2 00:00:00

    -- 两个日期的天数差

    date_diff(time1,time2):返回两个日期之间(time1-time2)的天数。

    eg:

    select datediff('2008-08-08','2008-08-01')

    -- 两个日期的时间差

    timediff(time1,time2):两个日期相减 time1 - time2,返回 time 差值。

    注意:timediff(time1,time2) 函数的两个参数类型必须相同。

    --- 两个日期得到指定差

    timestampdiff(unit,begin,end)

    返回end-begin的结果,其中begin和end是date或datetime格式

    例如:timestampdiff(year,birth,now()) 计算生日 返回两个日期之间的年份,未过生日减一


    做题的过程中,发现窗口函数也是常考内容,补充一下

    窗口函数:Mysql8.0以上版本支持窗口函数,窗口函数与分组聚合函数类似,但是每一行数据都生成一个结果。

    面对一些既要分组又要排序的TOP N问题,我们可以使用窗口函数快速得出结果.

    窗口函数和普通聚合函数区别如下:

    ··聚合函数是将多条记录聚合为一条;而窗口函数是每条记录都会执行,有几条记录执行完还是几条。

    ··聚合函数也可以用于窗口函数中

    使用方法:配合聚合窗口函数一起使用,例如SUM/AVG/COUNT/MAX/MIN等

    select * 

    from(

        select*,

            row_number() over (partition by 要分组的列名 order by 要排序的列名 desc) as 排名

        from 表名) as a

    where排名<=N;

    ROW_NUMBER() 依次排序且不会重复,不考虑并列名次的情况

    DENSE_RANK() 遇到重复值时连续排序,如果有并列名次的行,不占用下一名次的位置

    RANK() 跳跃排序,如果有并列名次的行,会占用下一名次的位置

    PERCENT_RANK() 百分位排序,遇到相同值的时候连续排序。


    case when语句

    "case

        when 列名= 条件值1 then 选择项1

        when 列名=条件值2 then 选项2.......

        else 默认值 end"

    ·经常会结合聚合函数(sum)一起来计算人数,金额····

    例如: select group, sum( case when ``` then 1 else 0 end)  as  ' 消费人数' 

    ·还有用于行转列的操作:

    例如将图1转换为图2

    select name as '姓名'

    ,max(case course when '语文' then score else 0 end) as '语文'

    ,max(case course when '数学' then score else 0 end) as '数学'

    ,max(case course when '英语' then score else 0 end) as '英语'

    from test.course_score group by name;


    刷题的过程中还会发现很多常见解题套路,梦回高中做数学题 _(:з」∠)_ 

    到时候再来总结

    相关文章

      网友评论

        本文标题:Mysql总结

        本文链接:https://www.haomeiwen.com/subject/kkeusktx.html