美文网首页
SQL 2020-03-15(未经允许,禁止转载)

SQL 2020-03-15(未经允许,禁止转载)

作者: 9_SooHyun | 来源:发表于2020-03-15 13:29 被阅读0次

    几个不错的在线学习+练习网站

    SQL动物园https://sqlzoo.net/wiki/
    SQL机器人https://sqlbolt.com/
    学SQL(SQL机器人的中文版,recommended)http://xuesql.cn/

    比较丰富但基础的练习题可以看,适合实践巩固:
    https://www.w3resource.com/sql-exercises/
    另外,leetcode也有SQL的练习题


    知识小结,以MySQL为例

    1.SQL基础

    SQL是一种statement声明式语言,它仅仅是声明了一个你想从原始数据中获得某种样式的结果范例,而不像编程那样需要明确指示计算机如何操作

    基本语法

    # 创建数据库
    CREATE DATABASE <数据库名>;
    CREATE SCHEMA <数据库名>;
    说明:CREATE SCHEMA is a synonym for CREATE DATABASE

    # 删除数据库
    DROP DATABASE <数据库名>;

    # 切换数据库
    USE <数据库名>;

    # 创建基本表
    CREATE TABLE <表名>
    (列名称1 数据类型,
    列名称2 数据类型,
    列名称3 数据类型);

    # 删除基本表
    DROP TABLE <表名>;

    # 增
    INSERT INTO <表名> (COL1, COL2, ...) VALUES (V1, V2, ...);

    # 删
    DELETE FROM <表名> WHERE ...;

    # 改
    UPDATE <表名> SET COL1=V1, COL2=V2 WHERE ...;

    # 查
    SELECT COL1, COL2, ... FROM <表名> WHERE ...;

    说明:MySQL默认打开safe update mode当safe update mode打开时,如果需要改动且存在WHERE子句,那么WHERE的筛选必须基于主键。即DELETE和UPDATE的WHERE条件必须基于主键,否则报错Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.
    关闭MySQL的safe update mode,可以通过命令SET SQL_SAFE_UPDATES = 0;

    2.SQL进阶

    DISTINCT
    返回目标字段中不重复的值,只能在select语句中使用
    SELECT DISTINCT col1, col2, ... FROM <表名> [WHERE conditions];

    • DISTINCT多对单列使用;对多列操作时,表示选取多列都不重复的数据,即多列拼接成一条记录,返回不重复的记录
    • DISTINCT返回的结果中不会过滤NULL,也就是可以包含NULL值

    In most cases, a DISTINCT clause can be considered as a special case of GROUP BY. For example, the following two queries are equivalent:

    SELECT DISTINCT c1, c2, c3 FROM t1
    WHERE c1 > const;
    
    SELECT c1, c2, c3 FROM t1
    WHERE c1 > const GROUP BY c1, c2, c3;
    

    Due to this equivalence, the optimizations applicable to GROUP BY queries can be also applied to queries with a DISTINCT clause. Thus, for more details on the optimization possibilities for DISTINCT queries

    JOIN ON
    JOIN ON = 按笛卡尔积【A×B={(x,y)|x∈A∧y∈B}】拼接多张表. The SQL JOIN clause is used whenever we have to select data from 2 or more tables.
    JOIN分为INNER JOIN / LEFT JOIN / RIGHT JOIN / FULL JOIN
    直接上表说明

    person表

    name age gender
    Alice 23 0
    Bob 24 1

    job表

    name job
    Alice Engineer
    Alice Officer
    Clark Manager

    下面开始JOIN

    • SELECT * FROM person INNER JOIN job ON person.name = job.name
    person.name age gender job.name job
    Alice 23 0 Alice Engineer
    Alice 23 0 Alice Officer

    INNER JOIN:person表与job表满足ON条件的记录进行笛卡尔乘积

    • SELECT * FROM person LEFT JOIN job ON person.name = job.name
    person.name age gender job.name job
    Alice 23 0 Alice Engineer
    Alice 23 0 Alice Officer
    Bob 24 1 NULL NULL

    LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行

    • SELECT * FROM person RIGHT JOIN job ON person.name = job.name
    person.name age gender job.name job
    Alice 23 0 Alice Engineer
    Alice 23 0 Alice Officer
    NULL NULL NULL Clark Manager

    RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行

    • SELECT * FROM person FULL JOIN job ON person.name = job.name
    person.name age gender job.name job
    Alice 23 0 Alice Engineer
    Alice 23 0 Alice Officer
    Bob 24 1 NULL NULL
    NULL NULL NULL Clark Manager

    FULL JOIN: 返回两表的全部记录,不满足ON条件的就置NULL

    SQL的执行顺序8步走——从FROM来,到ORDER BY去
    在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入

    FROM——加载原始表格
    WHERE——通过where筛选器挑出原始表中满足条件的子表,但无法与聚合函数一起使用;同时,不可使用select中的别名
    GROUP BY——分组。如果应用了group by,那么只为每个组保留一行记录
    HAVING——筛选分组。HAVING的出现就是为了解决WHERE无法与聚合函数一起使用的不足,几乎都与GROUP BY连用以实现记录分组+筛选出目标组。如先按国家分组,然后对每个国家计算gdp总量,筛选大于1000的:GROUP BY country HAVING SUM(gdp) > 1000
    --上面4步负责获取满足各种筛选条件后的记录,更重要
    --下面4步负责处理显示给人看的结果
    SELECT——挑拣需要的列
    DISTINCT——显示去重
    UNION——合并两个或多个 SELECT 语句的结果集。注意是上下合并而不是左右拼接
    ORDER BY——调整显示顺序

    SQL执行顺序(来源网络)
    sql执行流程图(来源网络)
    根据SQL的执行顺序,字段/表达式的别名在WHERE子句和GROUP BY子句都不能使用,因为此时别名还没有生效;而在order by中不仅可以使用别名,还可以直接使用字段的下标来进行排序,如:order by 1 desc

    条件判断CASE WHEN THEN ELSE END
    CASE WHEN就是编程中的if else, 在实际工作环境中,CASE WHEN的使用频率和SELECT差不多

    case
    when condition1 then result1
    when condition2 then result2
    ...
    else default
    end
    

    condition是待求值的表达式,如果它的返回值是真,则返回对应result
    例如:
    SELECT
    CASE
    WHEN salary <= 500 THEN '1'
    WHEN salary > 500 AND salary <= 600 THEN '2'
    WHEN salary > 600 AND salary <= 800 THEN '3'
    WHEN salary > 800 AND salary <= 1000 THEN '4'
    ELSE NULL END salary_class, -- 别名命名
    COUNT(*)
    FROM Table_A;

    分组排序row_number() over() or rank() over()

    • row_number() over(partition by col1 order by col2)
      很好理解,字面意思,按col1分组,组内按col2排序,返回行号
      row_number() over()
    • rank() over(partition by col1 order by col2)
      也很好理解,字面意思,按col1分组,组内按col2排序,返回排名 rank() over()
      行号是绝对顺序的,而排名是可以并列的

    查看mysql变量

    show variables [like "%variable_name%"]
    show variables like "%innodb_deadlock_detect%"

    查看mysql当前实时状态

    show status [like "%status_name%"]

    相关文章

      网友评论

          本文标题:SQL 2020-03-15(未经允许,禁止转载)

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