定义
SQL编程语言的语法是由ISO/IEC SC 32定义和维护的。该标准并不是免费的。尽管存在标准,SQL也不能在不做调整的情况下完全移植到不同的数据库。
语言元素
SQL语言分为几种语言元素,分别是:
- 关键字:用SQL语言定义的单词。它们要么是保留的(例如SELECT,COUNT和YEAR),要么是 不保留 的(例如ASC,DOMAIN和KEY)。
- 标识符:数据库对象(如表,列和模式)上的名称。标识符不能等于保留关键字,除非它是分隔符标识符。分隔标识符是指用双引号括起来的标识符,可以包含SQL标识符中通常不支持的字符,也可以与保留字相同,例如YEAR。
- 子句:语句和查询的组成部分。
- 表达式:可以产生标量值或由数据的列和行组成的表
- 谓词:指定可以评估为SQL三值逻辑(3VL)(真/假/未知)或布尔真值的条件,并用于限制语句和查询的作用或更改程序流。
- 查询:根据特定条件检索数据。
- 语句:对模式和数据产生持久影响,或者可能控制事务,程序流,连接,会话或诊断。
- 空格
操作符
操作符 | 描述 | 示例 |
---|---|---|
= | 等于 | Author = ‘Alcott’ |
<> | 不等于(很多数据库接受!=) | Author <> ‘Alcott’ |
> | 大于 | Author > ‘Alcott’ |
< | 小于 | Author <‘Alcott’ |
>= | 大于等于 | Author >= ‘Alcott’ |
<= | 小于等于 | Author <= ‘Alcott’ |
[NOT] BETWEEN [SYMMETRIC] | 在一个包容范围之间。如果第一个高于第二个,则SYMMETRIC反转范围界限 | Cost BETWEEN 100.00 AND 500.00 |
[NOT] LIKE [ESCAPE] | Contains a character pattern | Full_Name LIKE ‘%Will%’ |
[NOT] IN | 包含于 | DeptCode IN (101, 103, 209) |
IS [NOT] NULL | 是否空 | Address IS NOT NULL |
IS [NOT] TRUE or IS [NOT] FALSE | 真假 | PaidVacation IS TRUE |
IS NOT DISTINCT FROM | 等于或两者均为空 | Debt IS NOT DISTINCT FROM - Receivables |
AS | 查看结果时用于更改列名 | SELECT employee AS department1 |
SQL还有case表达式,在SQL标准中称为“搜索用例”:
CASE WHEN n > 0
THEN 'positive'
WHEN n < 0
THEN 'negative'
ELSE 'zero'
END
SQL按条件在源中出现的顺序测试WHEN
case表达式有两种简短形式:COALESCE和NULLIF。
- COALESCE表达式返回从左到右求出的第一个非NULL操作数的值,如果所有操作数均等于NULL,则返回NULL。
COALESCE(x1,x2)
- NULLIF表达式有两个操作数,如果两个操作数具有相同的值,则返回NULL,否则它具有第一个操作数的值。
NULLIF(x1, x2) --CASE WHEN x1 = x2 THEN NULL ELSE x1 END
注释
标准SQL允许两种格式的注释:-注释,以第一个换行符结尾;和/ 注释 /,可以跨越多行。
查询
SQL中最常见的操作(查询)使用声明性SELECT语句。 SELECT从一个或多个表或表达式中检索数据。标准SELECT语句对数据库没有持久影响。SELECT的某些非标准实现会产生持久影响,例如某些数据库中提供的SELECT INTO语法。
查询包括要包含在最终结果中的列的列表,通常在紧跟SELECT关键字之后。可以使用星号(“ *”)指定查询应返回查询表的所有列。
查询的子句具有特定的执行顺序[5],该顺序由右侧的数字表示。如下:
- FROM:指示要从中检索数据的表,可以包含可选的JOIN子句,以指定连接表的规则
- WHERE:包含一个比较谓词,该谓词限制了查询返回的行。 WHERE子句从结果集中消除比较谓词未评估为True的所有行。
- GROUP BY:将具有公共值的行投影到较小的行集中。 GROUP BY通常与SQL聚合函数结合使用,或从结果集中消除重复的行。
- HAVING:包含一个谓词,用于过滤GROUP BY子句产生的行。由于聚合函数作用于GROUP BY子句的结果,因此可以在HAVING子句谓词中使用聚合函数。
- ORDER BY:标识用于对结果数据进行排序的列,以及对数据进行排序的方向(升序或降序)。如果没有ORDER BY子句,则SQL查询返回的行顺序是不确定的。
- DISTINCT:消除重复数据。
- OFFSET:指定开始返回数据之前要跳过的行数。
- FETCH FIRST:指定要返回的行数。相反,某些SQL数据库具有非标准替代方案
子查询
查询可以嵌套,以便可以通过关系运算符或聚合函数将一个查询的结果用于另一个查询。嵌套查询也称为子查询。
SELECT isbn,
title,
price
FROM Book
WHERE price < (SELECT AVG(price) FROM Book)
ORDER BY title;
派生表
派生表用于在FROM子句中引用SQL子查询。本质上,派生表是可以从中选择或结合到的子查询。
SELECT b.isbn, b.title, b.price, sales.items_sold, sales.company_nm
FROM Book b
JOIN (SELECT SUM(Items_Sold) Items_Sold, Company_Nm, ISBN
FROM Book_Sales
GROUP BY Company_Nm, ISBN) sales
ON sales.isbn = b.isbn
数据处理
数据操作语言(DML)是SQL的子集,用于添加,更新和删除数据
- INSERT将行(正式元组)添加到现有表中
INSERT INTO example
(column1, column2, column3)
VALUES
('test', 'N', NULL);
- UPDATE修改一组现有的表行
UPDATE example
SET column1 = 'updated value'
WHERE column2 = 'N';
- DELETE从表中删除现有行
DELETE FROM example
WHERE column2 = 'N';
- MERGE用于合并多个表的数据。它结合了INSERT和UPDATE元素。
MERGE INTO table_name USING table_reference ON (condition)
WHEN MATCHED THEN
UPDATE SET column1 = value1 [, column2 = value2 ...]
WHEN NOT MATCHED THEN
INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...])
事务
事务是一组原子性的sql查询,或者说一个独立的工作单元,用于(如果有的话)包装DML操作。
- START TRANSACTION(或BEGIN WORK或BEGIN TRANSACTION,取决于SQL方言)标记了数据库事务的开始,该事务语句要么全部执行成功,要么全部执行失败。
- SAVE TRANSACTION(或SAVEPOINT)保存事务中当前点的数据库状态
CREATE TABLE tbl_1(id int);
INSERT INTO tbl_1(id) VALUES(1);
INSERT INTO tbl_1(id) VALUES(2);
COMMIT;
UPDATE tbl_1 SET id=200 WHERE id=1;
SAVEPOINT id_1upd;
UPDATE tbl_1 SET id=1000 WHERE id=2;
ROLLBACK to id_1upd;
SELECT id from tbl_1;
- COMMIT使事务中的所有数据更改永久生效
- ROLLBACK丢弃自上一次COMMIT或ROLLBACK以来的所有数据更改,而保留这些更改之前的数据。一旦COMMIT语句完成,就不能回滚事务的更改
- COMMIT和ROLLBACK终止当前事务并释放数据锁。
START TRANSACTION;
UPDATE Account SET amount=amount-200 WHERE account_number=1234;
UPDATE Account SET amount=amount+200 WHERE account_number=2345;
IF ERRORS=0 COMMIT;
IF ERRORS<>0 ROLLBACK;
数据定义
数据定义语言(DDL)管理表和索引结构。 DDL的最基本项目是CREATE,ALTER,RENAME,DROP和TRUNCATE语句
- CREATE在数据库中创建一个对象
CREATE TABLE example(
column1 INTEGER,
column2 VARCHAR(50),
column3 DATE NOT NULL,
PRIMARY KEY (column1, column2)
);
- ALTER以各种方式修改现有对象的结构,例如,将列添加到现有表或约束中
ALTER TABLE example ADD column4 INTEGER DEFAULT 25 NOT NULL;
- TRUNCATE以非常快速的方式删除表中的所有数据,删除表中的数据而不是表本身。它通常意味着后续的COMMIT操作,即无法回滚(与DELETE不同,数据不会写入日志以供以后回滚)。
TRUNCATE TABLE example;
- DROP通常无法恢复地删除数据库中的对象,即无法回滚
DROP TABLE example;
数据类型
SQL表中的每一列都声明该列可能包含的类型。 ANSI SQL包括以下数据类型。
字符串
- CHARACTER(n)(或CHAR(n)):固定宽度的n个字符的字符串,根据需要用空格填充
- CHARACTER VARYING(n) (or VARCHAR(n)): 宽度可变的字符串,最大大小为n个字符
二进制
- BINARY(n):固定长度的二进制字符串,最大长度为n
- BINARY VARYING(n)(或VARBINARY(n)):可变长度的二进制字符串,最大长度为n。
布尔型
- BOOLEAN数据类型可以存储值TRUE和FALSE。
数值型
- INTEGER (or INT), SMALLINT and BIGINT
- FLOAT, REAL and DOUBLE PRECISION
- NUMERIC(precision, scale) or DECIMAL(precision, scale)
- DECFLOAT(precision)
时间型
- DATE: 日期值 (e.g. 2011-05-03).
- TIME: 时间值 (e.g. 15:51:36).
- TIME WITH TIME ZONE: 包含时区详细信息的时间
- TIMESTAMP: 把date和time放到一个变量中
- TIMESTAMP WITH TIME ZONE: 与TIMESTAMP相同,但包含有关时区的详细信息。
时间间隔
- YEAR(precision): 年
- YEAR(precision) TO MONTH: 年月
- MONTH(precision): 月
- DAY(precision): 天数
- DAY(precision) TO HOUR:天数小时数
- DAY(precision) TO MINUTE: 数天,数小时和数分钟
- DAY(precision) TO SECOND(scale): 数天,小时,分钟和秒
- HOUR(precision): 小时
- HOUR(precision) TO MINUTE: 时分
- HOUR(precision) TO SECOND(scale): 时分秒
- MINUTE(precision): 分钟
- MINUTE(precision) TO SECOND(scale): 分秒
数据控制
数据控制语言(DCL)授权用户访问和操纵数据。它的两个主要声明是:
- GRANT: 授权一个或多个用户对一个对象执行一项操作或一组操作。
- REVOKE:取消授予,可能是默认授予。
GRANT SELECT, UPDATE
ON example
TO some_user, another_user;
REVOKE SELECT, UPDATE
ON example
FROM some_user, another_user;