赞
踩
本文针对关系型数据库的一般语法。限于篇幅,本文侧重说明用法,不会展开讲解特性、原理。
数据库(database)
- 保存有组织的数据的容器(通常是一个文件或一组文件)。数据表(table)
- 某种特定类型数据的结构化清单。模式(schema)
- 关于数据库和表的布局及特性的信息。模式定义了数据在表中如何存储,包含存储什么样的数据,数据如何分解,各部分信息如何命名等信息。数据库和表都有模式。列(column)
- 表中的一个字段。所有表都是由一个或多个列组成的。行(row)
- 表中的一个记录。主键(primary key)
- 一列(或一组列),其值能够唯一标识表中每一行。SQL(Structured Query Language),标准 SQL 由 ANSI 标准委员会管理,从而称为 ANSI SQL。各个 DBMS 都有自己的实现,如 PL/SQL、Transact-SQL 等。
SQL 语法结构包括:
子句
- 是语句和查询的组成成分。(在某些情况下,这些都是可选的。)表达式
- 可以产生任何标量值,或由列和行的数据库表谓词
- 给需要评估的 SQL 三值逻辑(3VL)(true/false/unknown)或布尔真值指定条件,并限制语句和查询的效果,或改变程序流程。查询
- 基于特定条件检索数据。这是 SQL 的一个重要组成部分。语句
- 可以持久地影响纲要和数据,也可以控制数据库事务、程序流程、连接、会话或诊断。例如:SELECT
与 select
、Select
是相同的。
;
)分隔。- -- 一行 SQL 语句
- UPDATE user SET username='robot', password='robot' WHERE username = 'root';
-
- -- 多行 SQL 语句
- UPDATE user
- SET username='robot', password='robot'
- WHERE username = 'root';
- ## 注释1
- -- 注释2
- /* 注释3 */
数据定义语言(Data Definition Language,DDL)是 SQL 语言集中负责数据结构定义与数据库对象定义的语言。
DDL 的主要功能是定义数据库对象。
DDL 的核心指令是 CREATE
、ALTER
、DROP
。
数据操纵语言(Data Manipulation Language, DML)是用于数据库操作,对数据库其中的对象和数据运行访问工作的编程语句。
DML 的主要功能是 访问数据,因此其语法都是以读写数据库为主。
DML 的核心指令是 INSERT
、UPDATE
、DELETE
、SELECT
。这四个指令合称 CRUD(Create, Read, Update, Delete),即增删改查。
事务控制语言 (Transaction Control Language, TCL) 用于管理数据库中的事务。这些用于管理由 DML 语句所做的更改。它还允许将语句分组为逻辑事务。
TCL 的核心指令是 COMMIT
、ROLLBACK
。
数据控制语言 (Data Control Language, DCL) 是一种可对数据访问权进行控制的指令,它可以控制特定用户账户对数据表、查看表、预存程序、用户自定义函数等数据库对象的控制权。
DCL 的核心指令是 GRANT
、REVOKE
。
DCL 以控制用户的访问权限为主,因此其指令作法并不复杂,可利用 DCL 控制的权限有:CONNECT
、SELECT
、INSERT
、UPDATE
、DELETE
、EXECUTE
、USAGE
、REFERENCES
。
根据不同的 DBMS 以及不同的安全性实体,其支持的权限控制也有所不同。
(以下为 DML 语句用法)
增删改查,又称为 CRUD,数据库基本操作中的基本操作。
INSERT INTO
语句用于向表中插入新记录。
插入完整的行
- INSERT INTO user
- VALUES (10, 'root', 'root', 'xxxx@163.com');
插入行的一部分
- INSERT INTO user(username, password, email)
- VALUES ('admin', 'admin', 'xxxx@163.com');
插入查询出来的数据
- INSERT INTO user(username)
- SELECT name
- FROM account;
UPDATE
语句用于更新表中的记录。
- UPDATE user
- SET username='robot', password='robot'
- WHERE username = 'root';
DELETE
语句用于删除表中的记录。TRUNCATE TABLE
可以清空表,也就是删除所有行。删除表中的指定数据
- DELETE FROM user
- WHERE username = 'robot';
清空表中的数据
TRUNCATE TABLE user;
SELECT
语句用于从数据库中查询数据。DISTINCT
用于返回唯一不同的值。它作用于所有列,也就是说所有列的值都相同才算相同。LIMIT
限制返回的行数。可以有两个参数,第一个参数为起始行,从 0 开始;第二个参数为返回的总行数。
ASC
:升序(默认)DESC
:降序查询单列
- SELECT prod_name
- FROM products;
查询多列
- SELECT prod_id, prod_name, prod_price
- FROM products;
查询所有列
- ELECT *
- FROM products;
查询不同的值
- SELECT DISTINCT
- vend_id FROM products;
限制查询结果
- -- 返回前 5 行
- SELECT * FROM mytable LIMIT 5;
- SELECT * FROM mytable LIMIT 0, 5;
- -- 返回第 3 ~ 5 行
- SELECT * FROM mytable LIMIT 2, 3;
子查询是嵌套在较大查询中的 SQL 查询。子查询也称为 内部查询或 内部选择,而包含子查询的语句也称为 外部查询或 外部选择。
SELECT
,INSERT
,UPDATE
或 DELETE
语句内或另一个子查询中。SELECT
语句的 WHERE
子句中添加。>
,<
,或 =
。比较运算符也可以是多行运算符,如 IN
,ANY
或 ALL
。()
括起来。子查询的子查询
- SELECT cust_name, cust_contact
- FROM customers
- WHERE cust_id IN (SELECT cust_id
- FROM orders
- WHERE order_num IN (SELECT order_num
- FROM orderitems
- WHERE prod_id = 'RGAN01'));
WHERE
子句用于过滤记录,即缩小访问数据的范围。WHERE
后跟一个返回 true
或 false
的条件。WHERE
可以与 SELECT
,UPDATE
和 DELETE
一起使用。WHERE
子句中使用的操作符SELECT
语句中的 WHERE
子句
- SELECT * FROM Customers
- WHERE cust_name = 'Kids Place';
UPDATE
语句中的 WHERE
子句
- UPDATE Customers
- SET cust_name = 'Jack Jones'
- WHERE cust_name = 'Kids Place';
DELETE
语句中的 WHERE
子句
- DELETE FROM Customers
- WHERE cust_name = 'Kids Place';
IN
操作符在 WHERE
子句中使用,作用是在指定的几个特定值中任选一个值。BETWEEN
操作符在 WHERE
子句中使用,作用是选取介于某个范围内的值。IN 示例
- SELECT *
- FROM products
- WHERE vend_id IN ('DLL01', 'BRS01');
BETWEEN 示例
- SELECT *
- FROM products
- WHERE prod_price BETWEEN 3 AND 5;
AND
、OR
、NOT
是用于对过滤条件的逻辑处理指令。AND
优先级高于 OR
,为了明确处理顺序,可以使用 ()
。AND
操作符表示左右条件都要满足。OR
操作符表示左右条件满足任意一个即可。NOT
操作符用于否定一个条件。AND 示例
- SELECT prod_id, prod_name, prod_price
- FROM products
- WHERE vend_id = 'DLL01' AND prod_price <= 4;
OR 示例
- SELECT prod_id, prod_name, prod_price
- FROM products
- WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
NOT 示例
- SELECT *
- FROM products
- WHERE prod_price NOT BETWEEN 3 AND 5;
LIKE
操作符在 WHERE
子句中使用,作用是确定字符串是否匹配模式。LIKE
。LIKE
支持两个通配符匹配选项:%
和 _
。%
表示任何字符出现任意次数。_
表示任何字符出现一次。% 示例
- SELECT prod_id, prod_name, prod_price
- FROM products
- WHERE prod_name LIKE '%bean bag%';
_ 示例
- SELECT prod_id, prod_name, prod_price
- FROM products
- WHERE prod_name LIKE '__ inch teddy bear';
JOIN
至少有一个公共字段并且它们之间存在关系,则该 JOIN
可以在两个或多个表上工作。JOIN
关键字,并且条件语句使用 ON
而不是 WHERE
。JOIN
保持基表(结构和数据)不变。JOIN
有两种连接类型:内连接和外连接。JOIN
关键字。在没有条件语句的情况下返回笛卡尔积。
- SELECT vend_name, prod_name, prod_price
- FROM vendors INNER JOIN products
- ON vendors.vend_id = products.vend_id;
- SELECT c1.cust_id, c1.cust_name, c1.cust_contact
- FROM customers c1, customers c2
- WHERE c1.cust_name = c2.cust_name
- AND c2.cust_contact = 'Jim Jones';
- SELECT *
- FROM Products
- NATURAL JOIN Customers;
- SELECT customers.cust_id, orders.order_num
- FROM customers LEFT JOIN orders
- ON customers.cust_id = orders.cust_id;
- SELECT customers.cust_id, orders.order_num
- FROM customers RIGHT JOIN orders
- ON customers.cust_id = orders.cust_id;
UNION
运算符将两个或更多查询的结果组合起来,并生成一个结果集,其中包含来自 UNION
中参与查询的提取行。UNION
基本规则
UNION ALL
。ORDER BY
子句,并且必须位于语句的最后。组合查询
- SELECT cust_name, cust_contact, cust_email
- FROM customers
- WHERE cust_state IN ('IL', 'IN', 'MI')
- UNION
- SELECT cust_name, cust_contact, cust_email
- FROM customers
- WHERE cust_name = 'Fun4All';
JOIN
中连接表的列可能不同,但在 UNION
中,所有查询的列数和列顺序必须相同。UNION
将查询之后的行放在一起(垂直放置),但 JOIN
将查询之后的列放在一起(水平放置),即它构成一个笛卡尔积。注意:不同数据库的函数往往各不相同,因此不可移植。本节主要以 Mysql 的函数为例。
文本处理
其中, SOUNDEX() 可以将一个字符串转换为描述其语音表示的字母数字模式。
- SELECT *
- FROM mytable
- WHERE SOUNDEX(col1) = SOUNDEX('apple')
YYYY-MM-DD
HH:MM:SS
- mysql> SELECT NOW();
-
- 2018-4-14 20:25:11
数值处理
汇总
AVG()
会忽略 NULL 行。
使用 DISTINCT 可以让汇总函数值汇总不同的值。
- SELECT AVG(DISTINCT col1) AS avg_col
- FROM mytable
ORDER BY
用于对结果集进行排序。
ASC
:升序(默认)DESC
:降序指定多个列的排序方向
- SELECT * FROM products
- ORDER BY prod_price DESC, prod_name ASC;
GROUP BY
子句将记录分组到汇总行中。GROUP BY
为每个组返回一个记录。GROUP BY
通常还涉及聚合:COUNT,MAX,SUM,AVG 等。GROUP BY
可以按一列或多列进行分组。GROUP BY
按分组字段进行排序后,ORDER BY
可以以汇总字段来进行排序。分组
- SELECT cust_name, COUNT(cust_address) AS addr_num
- FROM Customers GROUP BY cust_name;
分组后排序
- SELECT cust_name, COUNT(cust_address) AS addr_num
- FROM Customers GROUP BY cust_name
- ORDER BY cust_name DESC;
HAVING
用于对汇总的 GROUP BY
结果进行过滤。HAVING
要求存在一个 GROUP BY
子句。WHERE
和 HAVING
可以在相同的查询中。HAVING
vs WHERE
WHERE
和 HAVING
都是用于过滤。HAVING
适用于汇总的组记录;而 WHERE 适用于单个记录。使用 WHERE 和 HAVING 过滤数据
- SELECT cust_name, COUNT(*) AS num
- FROM Customers
- WHERE cust_email IS NOT NULL
- GROUP BY cust_name
- HAVING COUNT(*) >= 1;
(以下为 DDL 语句用法)
DDL 的主要功能是定义数据库对象(如:数据库、数据表、视图、索引等)。
CREATE DATABASE test;
DROP DATABASE test;
USE test;
普通创建
- CREATE TABLE user (
- id int(10) unsigned NOT NULL COMMENT 'Id',
- username varchar(64) NOT NULL DEFAULT 'default' COMMENT '用户名',
- password varchar(64) NOT NULL DEFAULT 'default' COMMENT '密码',
- email varchar(64) NOT NULL DEFAULT 'default' COMMENT '邮箱'
- ) COMMENT='用户表';
根据已有的表创建新表
- CREATE TABLE vip_user AS
- SELECT * FROM user;
DROP TABLE user;
添加列
- ALTER TABLE user
- ADD age int(3);
删除列
- ALTER TABLE user
- DROP COLUMN age;
修改列
- ALTER TABLE `user`
- MODIFY COLUMN age tinyint;
添加主键
- ALTER TABLE user
- ADD PRIMARY KEY (id);
删除主键
- ALTER TABLE user
- DROP PRIMARY KEY;
- CREATE VIEW top_10_user_view AS
- SELECT id, username
- FROM user
- WHERE id < 10;
DROP VIEW top_10_user_view;
- CREATE INDEX user_index
- ON user (id);
- CREATE UNIQUE INDEX user_index
- ON user (id);
- ALTER TABLE user
- DROP INDEX user_index;
SQL 约束用于规定表中的数据规则。
NOT NULL
- 指示某列不能存储 NULL 值。UNIQUE
- 保证某列的每行必须有唯一的值。PRIMARY KEY
- NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。FOREIGN KEY
- 保证一个表中的数据匹配另一个表中的值的参照完整性。CHECK
- 保证列中的值符合指定的条件。DEFAULT
- 规定没有给列赋值时的默认值。创建表时使用约束条件:
- CREATE TABLE Users (
- Id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增Id',
- Username VARCHAR(64) NOT NULL UNIQUE DEFAULT 'default' COMMENT '用户名',
- Password VARCHAR(64) NOT NULL DEFAULT 'default' COMMENT '密码',
- Email VARCHAR(64) NOT NULL DEFAULT 'default' COMMENT '邮箱地址',
- Enabled TINYINT(4) DEFAULT NULL COMMENT '是否有效',
- PRIMARY KEY (Id)
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
(以下为 TCL 语句用法)
START TRANSACTION
语句时,会关闭隐式提交;当 COMMIT
或 ROLLBACK
语句执行后,事务会自动关闭,重新恢复隐式提交。set autocommit=0
可以取消自动提交,直到 set autocommit=1
才会提交;autocommit 标记是针对每个连接而不是针对服务器的。START TRANSACTION
- 指令用于标记事务的起始点。SAVEPOINT
- 指令用于创建保留点。ROLLBACK TO
- 指令用于回滚到指定的保留点;如果没有设置保留点,则回退到 START TRANSACTION
语句处。COMMIT
- 提交事务。- -- 开始事务
- START TRANSACTION;
-
- -- 插入操作 A
- INSERT INTO `user`
- VALUES (1, 'root1', 'root1', 'xxxx@163.com');
-
- -- 创建保留点 updateA
- SAVEPOINT updateA;
-
- -- 插入操作 B
- INSERT INTO `user`
- VALUES (2, 'root2', 'root2', 'xxxx@163.com');
-
- -- 回滚到保留点 updateA
- ROLLBACK TO updateA;
-
- -- 提交事务,只有操作 A 生效
- COMMIT;

(以下为 DCL 语句用法)
CREATE USER myuser IDENTIFIED BY 'mypassword';
- UPDATE user SET user='newuser' WHERE user='myuser';
- FLUSH PRIVILEGES;
DROP USER myuser;
SHOW GRANTS FOR myuser;
GRANT SELECT, INSERT ON *.* TO myuser;
REVOKE SELECT, INSERT ON *.* FROM myuser;
SET PASSWORD FOR myuser = 'mypass';
;
为结束符,而存储过程中也包含了分号,因此会错误把这部分分号当成是结束符,造成语法错误。- DROP PROCEDURE IF EXISTS `proc_adder`;
- DELIMITER ;;
- CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_adder`(IN a int, IN b int, OUT sum int)
- BEGIN
- DECLARE c int;
- if a is null then set a = 0;
- end if;
-
- if b is null then set b = 0;
- end if;
-
- set sum = a + b;
- END
- ;;
- DELIMITER ;
- set @b=5;
- call proc_adder(2,@b,@s);
- select @s as sum;
- DELIMITER $
- CREATE PROCEDURE getTotal()
- BEGIN
- DECLARE total INT;
- -- 创建接收游标数据的变量
- DECLARE sid INT;
- DECLARE sname VARCHAR(10);
- -- 创建总数变量
- DECLARE sage INT;
- -- 创建结束标志变量
- DECLARE done INT DEFAULT false;
- -- 创建游标
- DECLARE cur CURSOR FOR SELECT id,name,age from cursor_table where age>30;
- -- 指定游标循环结束时的返回值
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;
- SET total = 0;
- OPEN cur;
- FETCH cur INTO sid, sname, sage;
- WHILE(NOT done)
- DO
- SET total = total + 1;
- FETCH cur INTO sid, sname, sage;
- END WHILE;
-
- CLOSE cur;
- SELECT total;
- END $
- DELIMITER ;
-
- -- 调用存储过程
- call getTotal();

触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行。
可以使用触发器来进行审计跟踪,把修改记录到另外一张表中。
MySQL 不允许在触发器中使用 CALL 语句 ,也就是不能调用存储过程。
BEGIN
和 END
当触发器的触发条件满足时,将会执行 BEGIN
和 END
之间的触发器执行动作。
注意:在 MySQL 中,分号;
是语句结束的标识符,遇到分号表示该段语句已经结束,MySQL 可以开始执行了。因此,解释器遇到触发器执行动作中的分号后就开始执行,然后会报错,因为没有找到和 BEGIN 匹配的 END。
这时就会用到DELIMITER
命令(DELIMITER 是定界符,分隔符的意思)。它是一条命令,不需要语句结束标识,语法为:DELIMITER new_delemiter
。new_delemiter
可以设为 1 个或多个长度的符号,默认的是分号;
,我们可以把它修改为其他符号,如$
-DELIMITER $
。在这之后的语句,以分号结束,解释器不会有什么反应,只有遇到了$
,才认为是语句结束。注意,使用完之后,我们还应该记得把它给修改回来。
NEW
和 OLD
NEW
和 OLD
关键字,用来表示触发器的所在表中,触发了触发器的那一行数据。INSERT
型触发器中,NEW
用来表示将要(BEFORE
)或已经(AFTER
)插入的新数据;UPDATE
型触发器中,OLD
用来表示将要或已经被修改的原数据,NEW
用来表示将要或已经修改为的新数据;DELETE
型触发器中,OLD
用来表示将要或已经被删除的原数据;NEW.columnName
(columnName 为相应数据表某一列名)提示:为了理解触发器的要点,有必要先了解一下创建触发器的指令。
CREATE TRIGGER
指令用于创建触发器。
语法:
- CREATE TRIGGER trigger_name
- trigger_time
- trigger_event
- ON table_name
- FOR EACH ROW
- BEGIN
- trigger_statements
- END;
说明:
BEFORE
或 AFTER
。INSERT
、UPDATE
或 DELETE
。;
来结尾。示例:
- DELIMITER $
- CREATE TRIGGER `trigger_insert_user`
- AFTER INSERT ON `user`
- FOR EACH ROW
- BEGIN
- INSERT INTO `user_history`(user_id, operate_type, operate_time)
- VALUES (NEW.id, 'add a user', now());
- END $
- DELIMITER ;
SHOW TRIGGERS;
DROP TRIGGER IF EXISTS trigger_insert_user;
来源:掘金
作者:静默虚空
原文:https://juejin.im/post/5c7e524af265da2d914db18f
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。