一、简介

SQL(Structured Query Language)是一种结构化查询语言,包含:数据定义语言(DDL:CREATE、DROP、ALTER),数据操纵语言(DML:INSERT、UPDATE、DELETE),数据控制语言(DCL:GRANT、REVOKE)。

二、数据定义语句

数据定义语句可以创建、删除或修改表、视图和索引等。

1、创建表

CREATE TABLE <表名>(
	<列名1> <列数据类型> [列完整性约束],
	<列名2> <列数据类型> [列完整性约束],
	……
	[表级完整性约束]	
)
  • 样例:

创建表并定义主键和外键:

create table Customer(
	id int primary key,
	name varchar(30) not null, 
	phone varchar(11),
	city varchar(50)
);

create table Product(
	id int primary key,
	number varchar(36),
	name varchar(100)
);

create table Orders(
	id bigint primary key,
	amount numeric(10, 2) not null,
	createdate datetime not null,
	customId int not null,
	foreign key(customId) references Customer(id)
);

create table OrderDetail(
	orderId bigint,
	productId int,
	quantity int not null,
	primary key(orderId, productId),
	foreign key(orderId) references Orders(id),
	foreign key(productId) references Product(id)
);
  • 常用完整性约束:

    • 主键约束:PRIMARY KEY

    • 唯一性约束:UNIQUE

    • 非空约束:NOT NULL

    • 参照完整性约束(外键):FOREIGN KEY

    • 用户自定义完整性约束:CHECK (约束条件)

2、修改表

ALTER  TABLE  <表名>
   [ADD  <新列名> <数据类型> [列完整性约束]]
   [DROP COLUMN <列名>]
   [MODIFY <列名> <新的数据类型>]
   [ADD CONSTRAINT <表级完整性约束>]
   [DROP CONSTRAINT <表级完整性约束>]];
  • 样例:

增加列:

alter table Product add price numeric(10, 2);

修改列;

alter table Customer modify phone varchar(13) default '';

删除列:

alter table Product drop column price;

3、删除表

DROP TABLE <表名> RESTRICT | CASCADE

说明:

RESTRICT表示要删除的表不能被其他表的约束所引用(CHECK、FOREIGN KEY等),不能有视图、触发器、存储过程或函数等。

CASCADE表示删除表时将相关的依赖对象一起删除。

样例:

DROP TABLE OrderDetail RESTRICT

4、索引

  • 需要建索引的情况

    • 搜索频繁的列上创建索引,可以加快搜索的速度

    • 经常用于表之间连接的列上(外键)创建索引,可以加快连接的速度

    • 经常需要根据范围进行搜索的列(索引已排序,其指定的范围是连续的)

    • 经常需要排序的列

  • 不需要建索引的情况

    • 在查询中很少使用的列

    • 只有很少数据值的列

    • text、iamge等类型的列

    • 当修改时的性能远远大于检索时的性能时

  • 创建索引

CREATE [UNIQUE] [CLUSTER] INDEX <索引名>  ON <表名> (<列名>[<升降序>][,<列名>[<升降序>]])

如果不指定升降序(ASC/DESC),默认为升序。

样例:

CREATE UNIQUE INDEX IDX_CUSTOMER_PHONE on Customer(phone);
  • 删除索引
DROP INDEX <索引名> ON <表名>

样例:

DROP INDEX IDX_CUSTOMER_PHONE on Customer;

三、数据操纵语句

数据操纵语句可以增加、删除或修改表中的记录。

1、插入

  • 插入单行
INSERT INTO <表名> [(<列名1><列名2>,……,<列名n>)]
VALUES(<列值1><列值2>,……,<列值n>) 

列名和列值对应,没有列出的列的值为空。如果省略列名序列,则插入的列值和表定义时列的顺序一致。

样例:

insert into Customer values(100, 'Tom', '18012345678');

insert into Product(id, name) values(1, 'Book');
  • 插入多行

将子查询的结果插入到指定表中:

INSERT INTO <表名> [(<列名1><列名2>,……,<列名n>)] 
子查询;

子查询结果与列名序列要对应,如果省略列名序列,则子查询结果必须和指定表中的列一致。

样例:

商品销售总量表:TotalSales(productId, total);

insert into TotalSales(productId, total)
select productId, sum(quantity) from OrderDetail group by productId;

2、删除

删除表中的一行或多行记录:

DELETE FROM <表名> [WHERE <条件>];

样例:

delete from Customer where name = 'Tom';

delete from OrderDetail where orderId in (select orderId from Orders where customId = 100);

3、修改

修改表中一行或多行记录中的某些值:

UPDATE <表名> 
SET <列名>=<表达式>[, <列名>=<表达式>]
[WHERE<条件>];

样例:

update Customer set name = 'Lucy' where phone = '18010012002';

update Product set price = price * 0.9 where id in (
select productId from OrderDetail
group by productId
having sum(quantity) < 10
);

4、事务

在SQL中,事务相关的语句有三条:BEGIN TRANSACTIONCOMMITROLLBACK

  • BEGIN TRANSACTION

开启事务

  • COMMIT

提交事务:将事务中所有对数据库的修改写到磁盘上的物理数据库中。

  • ROLLBACK

事务回滚:事务的执行中发生了某种异常,不能继续执行,系统将事务中对数据库的所有已完成的操作全部撤销,回滚到事务开始时的状态。

四、数据控制语句

数据控制语句可以用来设置或更改数据库用户或角色权限(不同数据库下语句不同),例如:

允许用户创建表、删除表的权限或所有权限:

GRANT CREATE TABLE TO username;
GRANT CREATE ANY TABLE TO username;

GRANT DROP ANY TABLE TO username;

GRANT sysdba TO username;

收回用户权限:

REVOKE CREATE TABLE FROM username

五、查询

查询(检索)操作是对已存在的表或视图进行数据检索,不会改变数据本身。

SELECT [ALL|DISTINCT] <列名或表达式> [别名1] [<列名或表达式> [别名2]]
FROM <表名或视图名> [表别名1] [<表名或视图名> [表别名2]]
[WHERE <条件表达式1>]
[GROUP BY <列名1> [HAVING <条件表达式2>]]
[ORDER BY <列名2>] [ASC|DESC] 

1、DISTINCT

DISTINCT的作用范围是所有目标列,在SELECT子句中只出现一次。

SELECT DISTINCT name FROM Customer;

2、别名

在查询时可以为查询列设置别名。

SELECT number 商品编码, name 商品名称 FROM  Product;

3、表达式或常量

SELECT语句中可以包含算术运算表达式(+ - * /)或常量,表达式的运算对象为常量或列。

SELECT id, customId, amount*0.8 FROM Orders;

select '电话:', phone from Customer;

4、聚合函数

SQL提供的聚合函数如下:

  • COUNT( * ):统计表中数据行数;

  • COUNT(< 列名>):统计表中某一列值的个数;

  • SUM(< 列名>):计算某一列值的总和;

  • AVG(< 列名>):计算某一列值的平均数;

  • MAX(< 列名>):计算某一列中的最大值;

  • MIN(< 列名>):计算某一列中的最小值。

其中,除了COUNT(*)外,其它聚合函数在计算时会忽略空值。

<列名>前加DISTINCT保留字,可以将查询结果中的列去掉重复值后再做计算。

样例:

SELECT COUNT(*) FROM Customer;

SELECT COUNT(DISTINCT name) FROM  Customer;

5、条件查询

WHERE子句中常用的查询条件有:

  • 普通比较:<、<=、>、>=、=、!=、 < >、!>、!<

  • 条件连接:AND、OR、NOT

  • 字符匹配:LIKE、NOT LIKE

      <列名> [NOT] LIKE <字符串常数> [ESCAPE <转义字符>]
    

    [NOT] LIKE的比较值中可以包含通配符,%表示任意长度的字符串,_表示单个字符。如果查询的字符串本身包含%_,则要使用ESCAPE <转义字符>对通配符转义:

      SELECT name, phone FROM Customer WHERE name LIKE '王\_' ESCAPE '\'; 
    
  • 集合:IN、NOT IN

  • 空值:IS NULL、IS NOT NULL

  • 范围:BETWEEN A AND B、NOT BETWEEN A AND B

6、分组查询

  • GROUP BY

使用GROUP BY子句可以将数据按某一列或多列值按值相同的原则分组,分组后可以对每组数据进行指定的操作;分组查询通常和聚合函数一起使用。

使用GROUP BY子句后,SELECT子句的列名列表中只能出现分组属性和聚合函数。

SELECT productId, SUM(quantity) 
FROM OrderDetail 
GROUP BY productId;
  • HAVING

使用HAVING子句可以对分组后的结果进行过滤,选择满足条件的组。

SELECT productId, MAX(quantity), MIN(quantity) FROM OrderDetail
GROUP BY productId
HAVING COUNT(*)>5 ;

7、排序查询

使用ORDER BY子句可以将查询结果按指定的列值顺序排列,默认为升序。

SELECT * FROM Product ORDER BY name, number DESC;

ORDER BY子句只能用于对最终查询结果排序,不能对中间结果排序;因此ORDER BY子句只能出现在最后。

8、连接查询

  • 表间连接
select Customer.id, name, Orders.id, amount, createdate from Customer, Orders
where Customer.id = Orders.customId and city='ShangHai';
  • 内连接
select Customer.id, name, Orders.id, amount, createdate 
from Customer INNER JOIN Orders on Customer.id = Orders.customId 
where city='ShangHai';
  • 自连接

表与自身进行的连接:

select D.* from Customer C, Customer D
where C.city = D.city and C.name = 'Tom';
  • 外连接

    外连接与普通连接不同,普通连接只查询出满足连接条件的数据;外连接以指定表为连接主体,将主体表中不满足连接条件的数据也会查询出来。

    • 左外连接
      LEFT JOIN …… ON ……
    
    • 右外连接
      RIGHT JOIN …… ON ……
    

9、嵌套查询

一个SELECT - FROM - WHERE语句构成一个查询块。将一个查询块嵌套在另一个查询块的WHERE或HAVING子句的条件表达式中的查询,称为嵌套查询。

其中子查询中不能使用ORDER BY语句。

SELECT name, phone FROM Customer 
WHERE id = (SELECT customId FROM Orders WHERE id=1);

10、集合查询

进个集合操作的各查询结果必须是相容的,即列数相同且对应的属性列的数据类型也相同。

  • 并集(UNION)
SELECT * FROM Customer WHERE city='BeiJing'
UNION
SELECT * FROM Customer WHERE city='ShangHai';
  • 交集(INTERSECT)
SELECT * FROM Product WHERE name='Banana' 
INTERSECT
SELECT * FROM Product WHERE price>10;
  • 差集(EXCEPT)
SELECT * FROM Customer WHERE city='BeiJing'
EXCEPT
SELECT * FROM Customer WHERE name like 'To%'; 

六、常用SQL

工作中常用SQL:

1、创建备份表

CREATE TABLE IF NOT EXISTS Product_backup like Product;
INSERT INTO Product_backup (select * from Product WHERE id in (100, 101, 102));

2、不存在时才插入数据

INSERT INTO Customer (id, name, phone) 
(select 505, 'Albert', '17112349876' from DUAL 
where not exists (select 1 from Customer where ID = 505));
参考资料:
  • 《数据库原理》