zoukankan      html  css  js  c++  java
  • [数据库SQL实战] 基本语法记录

    本文是个人在练习数据库相关习题所使用的SQL关键字函数简单使用样例,用以备忘。
    本文内容主要是再加工,对大部分SQL关键字和函数都演示了简单的测试使用样例
    通过举例的方式,粗略地介绍了其基本使用方法。


    DATABASES 数据库

    创建 CREATE

    创建数据库

    -- 如果不存在test数据库,就创建字符集为utf8的test数据库
    CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8;
    

    查看 SHOW/USE

    查看数据库信息

    -- 显示数据库列表
    SHOW DATABASES;
    -- 显示创建数据库信息 (G表示竖着打印)
    SHOW CREATE DATABASE testG;
    

    切换数据库(环境)

    -- 切换到test数据库
    USE test
    -- 注1:分号可加可不加
    -- 注2:可以直接切换,不管当前环境
    

    查看数据库的数据表列表

    -- 通过information_schema.TABLES获得所有数据库的表名,指定获取哪个数据库的表名
    SELECT table_name 
    FROM information_schema.TABLES 
    WHERE TABLE_SCHEMA='employees';
    
    -- 显示当前环境下数据表列表
    SHOW TABLES;
    -- 可以显示直接指定环境下表格列表
    SHOW TABLES FROM DATABASES;
    

    MySQL 中的 information_schema 数据库

    删除 DROP

    删除数据库

    -- 删除数据库test
    DROP DATABASES test;
    

    TABLE 数据表 (重点)

    创建 CREATE

    创建数据表

    -- 正常创建数据表
    -- 学生表students 
    CREATE TABLE IF NOT EXISTS students (
        stu_no char(10) NOT NULL,
        name varchar(10) NOT NULL,
        gender int(11) NOT NULL,
        PRIMARY KEY (stu_no)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- 复制已有表的结构建立新表
    -- stu_test表与students表结构一样(主键和外键都有) 但是个空表
    CREATE TABLE IF NOT EXISTS stu_test LIKE students;
    
    -- 基于已有表的数据建立新表
    -- stu_test2表与students表结构类似(字段和类型都一样,但主键和外键没有)
    CREATE TABLE IF NOT EXISTS stu_test2 AS SELECT * FROM students;
    

    查看 SHOW/DESC/SELECT

    查看数据表信息

    -- 显示创建数据表信息 (G表示竖着打印)
    SHOW CREATE TABLE studentsG;
    
    -- 显示数据表字段定义信息
    DESC students;
    -- 等同于
    SHOW COLUMNS FROM students;
    

    查看表格数据

    -- 显示students表格所有数据
    SELECT * FROM students;
    

    修改 INSERT INTO/REPLACE/UPDATE/RENAME/ALTER

    插入数据到表格

    -- 正常插入数据到表格
    INSERT INTO students(stu_no, name, gender, class_no) 
    VALUES("10001", "张三", 1, "201603"), 
    ("10002", "王喜", 0, "201604");
    -- 注意:如果某列关联了外键,那对应的外键必须有相应内容,否则会报以下错误
    -- ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`students`, CONSTRAINT `students_ibfk_1` FOREIGN KEY (`class_no`) REFERENCES `classes` (`class_no`))
    INSERT INTO classes(class_no, number)  
    VALUES("201603", 46), ("201604", 44);
    
    -- 直接从已有数据表插入数据到新表
    -- 将students表stu_no大于10000的数据插入stu_test表
    INSERT INTO stu_test AS SELECT * FROM students WHERE stu_no > 10000;
    

    更新数据到表格

    -- 更新stu_test表stu_no字段的值 将该字段的值+2(字符也适用)
    UPDATE stu_test SET stu_no = stu_no + 2;
    
    -- 将表students中stu_no='10002'的class_no改为'201605'
    -- 使用REPLACE关键字更新数据 
    REPLACE INTO students(stu_no, name, gender, class_no) VALUES('10002', '王喜', 0, '201605');
    -- 使用REPLACE函数更新数据 直接选择字段更新
    UPDATE students SET class_no=REPLACE(class_no, '201604', '201605') WHERE stu_no='10002';
    -- 直接使用UPDATE关键字
    UPDATE students SET class_no='201605' WHERE stu_no='10002';
    

    更改数据表名称

    -- 将表stu_test2改成stu_test3
    RENAME stu_test2 TO stu_test3;
    -- 以上语句,等同于
    ALTER TABLE stu_test2 RENAME stu_test3;
    

    删除 DROP/DELETE

    删除表格数据

    -- 删除表格数据
    -- 清空students表数据
    DELETE FROM students;
    

    删除表格

    -- 删除数据表students
    DROP TABLES students;
    

    关键字

    ORDER BY [AES/DESC] 排序

    -- 先进行逆序排序,然后只输出第一个 
    -- 对hire_date字段排序降序,此时最晚的时间排在第一个,再用LIMIT取出
    SELECT * FROM employees ORDER BY hire_date DESC LIMIT 1;
    

    LIMIT m,n 限制输出

    -- 入职时间hire_date 排名倒数order by ? desc 第三limit 2,1
    SELECT * FROM employees ORDER BY hire_date DESC LIMIT 2,1;
    

    DISTINCT 去重

    -- 给入职时间排名(去重)
    select distinct hire_date from employees order by hire_date desc;
    

    GROUP BY ... HAVING 分组

    -- 计数使用count 通过group by对每个员工编号分组 通过having进行条件筛选
    SELECT emp_no, COUNT(emp_no) AS t FROM salaries GROUP BY emp_no HAVING t > 15;
    

    LIKE 含有某字符串的信息

    -- 找出描述信息description包含'robot'的电影分类 
    SELECT f.category_id, f.description
    FROM film AS f 
    WHERE f.description LIKE '%robot%';
    

    IN/NOT IN (不)从中选取

    -- 从manager表中选出所有manager员工emp_no, 再从员工表反选
    SELECT emp_no FROM employees WHERE emp_no NOT IN (SELECT emp_no FROM dept_manager);
    

    EXISTS/NOT EXISTS (不)存在条件成立的值

    -- exists()就类似一个函数 
    -- 输入de.emp_no 输出是否存在'e.emp_no=de.emp_no'等式成立 返回T/F
    SELECT *
    FROM employees AS e
    WHERE NOT EXISTS (
    	SELECT * 
        FROM dept_emp AS de 
        WHERE e.emp_no=de.emp_no
    );
    
    • 用 NOT EXISTS 关键字的方法如下:
      意在 employees 中挑选出令(SELECT * FROM dept_emp WHERE emp_no = employees.emp_no)不成立的记录

    EXISTS对外表用loop逐条查询,每次查询都会查看EXISTS的条件语句,
    当 EXISTS里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返回当前loop到的这条记录;
    反之如果EXISTS里的条 件语句不能返回记录行,则当前loop到的这条记录被丢弃,
    EXISTS的条件就像一个bool条件,当能返回结果集则为true,不能返回结果集则为false。


    VIEW 视图

    创建 CREATE

    建立视图

    -- 创建视图stu_view 有字段name和sc(学号stu_no和班号class_no的组合)
    CREATE VIEW stu_view AS SELECT name, CONCAT(stu_no, ' ', class_no) AS sc FROM students;
    

    查看 SHOW/SELECT

    -- 显示创建视图信息 (G表示竖着打印)
    SHOW CREATE VIEW stu_view G;
    
    -- 同数据表一样
    -- 显示视图字段定义信息
    DESC stu_view;
    -- 等同于
    SHOW COLUMNS FROM stu_view;
    
    -- 查看视图内容
    SELECT * FROM stu_view;
    

    删除 DROP/DELETE

    删除视图数据

    -- 删除视图stu_view 字段sc = '10001 201603'的数据
    DELETE FROM stu_view WHERE sc = '10001 201603';
    

    删除视图

    DROP VIEW stu_view;
    

    INDEX 索引

    创建 CREATE/ALTER

    建立索引

    -- 给students表的stu_no字段创建索引
    CREATE INDEX idx_stu_no ON students(stu_no);
    -- 给students表的name字段其中5个字节创建索引
    CREATE INDEX idx_name ON students (name(5));
    
    -- 给students表的stu_no字段添加索引
    ALTER TABLE students ADD INDEX(stu_no);
    

    查看 SHOW/FORCE INDEX

    查看表格索引

    -- 显示students表的索引列表(主键索引、外键索引、唯一索引、所添加的索引)
    SHOW INDEX FROM students;
    

    强制使用索引

    -- 在查询students表stu_no字段大于"10001"的数据时,强制其使用所建立的索引
    SELECT stu_no, name FROM students FORCE INDEX(idx_stu_no) WHERE stu_no > "10001";
    
    • 实例
    -- MySQL中,使用 FORCE INDEX 函数进行强制索引查询
    EXPLAIN SELECT * FROM salaries FORCE INDEX(idx_emp_no) WHERE emp_no=10005;
    SELECT * FROM salaries WHERE emp_no=10005; -- 4ms (+5ms)
    SELECT * FROM salaries FORCE INDEX(idx_emp_no) WHERE emp_no=10005; -- 2ms (+1ms)
    

    MySQL force Index 强制索引概述
    Mysql中的force index和ignore index

    删除 DROP/ALTER

    删除索引

    -- 删除students表的idx_name索引
    DROP INDEX idx_name ON students;
    
    -- 删除students表的idx_name索引
    ALTER TABLE students DROP INDEX idx_name;
    

    TRIGGER 触发器

    创建 CREATE

    建立触发器

    -- 创建触发器'stu_sync' 
    -- 当students表插入数据后,将指定数据插入stu_test表内
    DELIMITER $$
    CREATE TRIGGER stu_sync 
    AFTER INSERT ON students FOR EACH ROW  
    BEGIN      
        INSERT INTO stu_test VALUES(NEW.stu_no, NEW.name, NEW.gender, NEW.class_no); 
    END$$
    DELIMITER ;
    

    MySQL官方文档:触发器实例

    查看 SHOW/SELECT

    显示所创建的触发器

    -- 显示创建触发器的信息 (G表示竖着打印)
    SHOW CREATE TRIGGER stu_syncG;
    
    -- 所有创建的触发器都存放在INFORMATION_SCHEMA数据库的TRIGGERS表格
    SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='stu_sync';
    
    -- 显示本环境(数据库)下的触发器
    SHOW TRIGGERS;
    

    删除 DROP

    删除触发器

    -- 删除触发器stu_sync
    DROP TRIGGER stu_sync;
    

    COLUMNS 字段(列)

    查看 SHOW

    显示表格字段

    -- 显示数据表students的索引字段信息
    SHOW COLUMNS FROM students;
    

    添加 ALTER ... ADD

    添加字段/主键/外键

    -- 给students表添加字段class_no
    ALTER TABLE students ADD class_no varchar(10) NOT NULL;
    -- 添加多个字段
    ALTER TABLE students ADD a INT,ADD b INT,ADD c INT;
    
    -- 给classes表添加主键class_no
    ALTER TABLE classes ADD PRIMARY KEY(class_no);
    
    -- 给students表添加外键class_no 关联classes表
    ALTER TABLE students ADD FOREIGN KEY (class_no) REFERENCES classes(class_no);
    -- 注意:如果关联表没有主键,或所管理列不是主键,会出现以下报错。
    -- ERROR 1215 (HY000): Cannot add foreign key constraint
    

    查看 SELECT

    查看表格的所有外键

    -- 查看数据库test的students表所有字段所关联的外键
    SELECT TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, 
        REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
    WHERE CONSTRAINT_SCHEMA ='test' AND
    REFERENCED_TABLE_NAME = 'students';
    -- 特别在想要删除该表,但因为其他表关联它作为外键而无法删除的时候
    -- Cannot delete or update a parent row: a foreign key constraint fails
    

    修改 ALTER ... MODIFY/CHANGE

    修改字段/主键/外键

    -- 给students表的字段修改类型
    ALTER TABLE students MODIFY b tinyint NOT NULL DEFAULT 1;
    ALTER TABLE students MODIFY a varchar(10);
    
    -- 给students表已经填入数据的字段 缩小数据类型
    ALTER TABLE students MODIFY stu_no char(6);
    
    -- 给students表的字段修改名称和类型
    ALTER TABLE students CHANGE b c CHAR(20);
    

    删除 ALTER ... DROP

    删除字段/主键/外键

    -- 删除字段c
    ALTER TABLE students DROP COLUMN c;
    
    -- 给students表删除外键'students_ibfk_1'
    ALTER TABLE students DROP FOREIGN KEY students_ibfk_1;
    

    FUNCTION 函数

    常用函数

    EXPLAIN 查看执行计划

    -- 执行计划 EXPLAIN
    EXPLAIN SELECT * FROM employees;
    
    • EXPLAIN 介绍

    EXPLAIN是一个执行SQL语句的模拟优化器,可以通过EXPALIN来查看增删查改操作的执行计划,即MySQL是如何处理sql语句,分析查询语句或者表结构的性能。
    作用 通过查看EXPALIN结果,可以知道
    1、表的读取顺序
    2、数据读取操作的操作类型
    3、哪些索引可以使用
    4、哪些索引被实际使用
    5、表之间的引用
    6、每张表有多少行被优化器查询

    CONCAT/CONCAT_WS/GROUP_CONCAT 字符串拼接函数

    -- 取巧 直接手动加空格作为分隔符 
    SELECT CONCAT(last_name, ' ' ,first_name) AS Name 
    FROM employees;
    
    -- 使用CONCAT_WS()函数  
    SELECT CONCAT_WS(' ', last_name, first_name) AS Name
    FROM employees;
    
    -- GROUP_CONCAT()函数的基本使用
    SELECT dept_no, group_concat(emp_no) AS employees
    FROM dept_emp
    GROUP BY dept_no
    
    • CONCAT()函数用法 简述

    CONCAT(str1,str2,…)
    返回结果为连接参数产生的字符串。如有任何一个参数为NULL,则返回值为NULL。
    CONCAT_WS(separator,str1,str2,...)
    CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。
    分隔符可以是一个字符串,也可以是其它参数。

    mysql多个字段拼接
    concat、concat_ws、group_concat函数用法

    CURRENT_TIMESTAMP 获取时间

    • MySQL 获取当前时间函数:

    current_timestamp() localtime() localtimestamp() sysdate()

    • MySQL 获取当前日期:

    curdate() = current_date()

    SUBSTR/RIGHT/LENGTH 字符串切割相关函数

    • RIGHT(s,n)

    返回字符串 s 的后 n 个字符

    • SUBSTR(s,start,len)

    从字符串 s 的 start 位置截取长度为 len 的子字符串

    • LENGTH(s)/CHAR_LENGTH(s)

    返回字符串 s 的字符数

    MySQL 函数

    创建函数

    样例

    -- 创建一个输入字符串s 返回'Hello, $s!'
    CREATE FUNCTION `hello`(s CHAR(20)) RETURNS char(50) 
    RETURN CONCAT('Hello, ', s, '!')
    
    -- 查看函数信息
    SHOW CREATE FUNCTION helloG;
    
    -- 使用函数hello
    SELECT hello('world') AS `result`;
    

    MySQL官方文档:创建函数

    • 实例:leetcode 数据库 176、第二高的薪水
    CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
    BEGIN
        -- 在limit中参数不可以有运算。如果想要运算,则需要用set语句定义好变量
        SET N = N - 1;
        RETURN (
            SELECT IFNULL((
                SELECT DISTINCT Salary
                FROM Employee
                ORDER BY Salary DESC
                LIMIT N,1), null
            ) AS getNthHighestSalary
        );
    END
    
  • 相关阅读:
    特殊集合
    推箱子
    集合
    数组

    循环语句 练习题
    穷举与迭代
    循环语句
    练习题
    switch case
  • 原文地址:https://www.cnblogs.com/slowbirdoflsh/p/11257449.html
Copyright © 2011-2022 走看看