SQL简介及常用SQL
一、简介
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 TRANSACTION
、COMMIT
和ROLLBACK
。
- 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));
参考资料:
- 《数据库原理》