SQL 简明教程
SQL(Structed Query Language)是结构化查询语句,在如今各类系统中有广泛的应用。在多次 No SQL 浪潮中依然生存下来,如今依然有着强大的生命力。是值得花时间投资的学习的一门技能。
SQL 是一种标准,由美国国家标准化组织(ANSI)制定
RDBMS 是关系型数据库管理系统。 比如 SQL Server、MySQL、Oracle 等。
在不同的 RDBMS 中都有自己的 SQL 扩展。
SQL 可以分成 DML(数据操作语言) 、DDL(数据定义语言) 以及DCL(数据控制语言)。
最简单区分这三者的方法就是:
- 操作表中数据的操作就是 DML
- 操作数据库表、视图等操作就是 DDL
- 操作数据库及数据库权限的就是 DCL
本文实践的环境是 MySQL
DML 基础
c 代表列名,v 代表值
SELECT
select 用于从数据库中查询数据。
有两种使用方式,一种是将表中的列全部查询出来,一种只查询出来指定的列。
查询全部列:
select * from table_name
查询指定列:
select c1, c2, c3 from table_name
在返回的数据中,有些列的值是重复的,可以使用 distinct 来返回一列的唯一值:
select distinct c2 from table_name
如果需要在查询的的过程中加入条件,那就需要使用 where 来指定查询条件:
select * from table_name where c1 = v1;
where 支持的运算符如下:
运算符 | 描述 |
---|---|
= | 等于 |
<> | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
BETWEEN | 在某个范围内 |
LIKE | 模糊查询 |
假如说不止一个条件,可以使用 AND 和 OR 来连接多个 条件,AND 和 OR 可以组合使用。
select * from table_name where c1 = v1 and c2 = v2 or c3 <> v3;
使用 select 查询出来的结果的顺序可能不是想要的,那么就可以使用 ORDER BY 来对结果进行排序,order by 默认使用的是升序排序。
使用 desc 来进行降序排序:
select * form table_name where c1 = v1 order by c1 desc;
对多个字段使用 order by:
select * from table_name where c1 = v1 order by c1, c2;
对不同的字段使用不同的排序规则:
select * from table_name where c1 = v1 order by c1 asc, c2 desc;
INSERT INTO
insert into 用于向数据库中插入数据。
两种使用方式,一种是直接插入表中,不指定列,这样需要为每一列都填充数据,否则会报错:
insert into table_name values (v1, v2, v3, v4);
也可以指定列:
insert into table_name (c2, c3, c4) values (v2, v3, v4);
UPDATE
update 用于更新数据,在更新数据的时候也可以使用 where 来限定某些条件的数据可以被更新。
update table_name set c1 = v1 where c1 = v;
DELETE
delete 用于删除表中的数据,可以使用 where 删除限定的数据,也可以删除全部数据。
delete from table_name where c1 = v1;
删除全部数据:
delete from table_name;
SELECT TOP
用于返回指定的记录的条数:
select top 2 * from table_name;
但是这个特性在有的数据库中不支持,但是有相应的替代方案可以选择,在 MySQL 中可以这样实现:
select * from table_name limit 2
LIKE
like 用于 where 子句中进行模糊查询。
表示查询 c1 列以 bar 开头的记录。
select * from table_name where c1 like 'bar%';
like 支持如下的通配符:
通配符 | 备注 |
---|---|
% | 替代一个或者多个字符 |
_ | 仅替代一个字符 |
[chars] | 字符列中的任何单一字符(MySQL 不支持) |
[^chars] 或者 [!chars] | 不在字符列中的任何单一字符(MySQL不支持) |
如果想使用 like 来排除条件,可以使用 not like。
在 MySQL 中,还支持正则表达式,可以使用 REGEXP(RLIKE) 和 NOT REGEXP(NOT RLIKE)
IN
in 可以指定 where 子句中在固定范围的内进行查询:
select * from table_name where c1 in (v1, v2, v3);
BETWEEN AND
between and 可以在 where 子句中指定查询的范围。
select * from table_name where c1 between v1 and v2;
between and 同样可以使用 not 来表示查询不在这个范围内的数据,用法如下:
select * from table_name where c1 not between v1 and v2;
between and 在不同的数据库中有不同的表现
ALIAS
在 SQL 进行查询的过程中,可以为列名和表名都增加别名。
为列增加别名:
select c1 as c1_alias from table_name;
为表增加别名:
select * from table_name as table_name_alias;
多表查询
SQL 支持同时查询多个表。
select a.c1,b.c2 from table1 as a, table2 as b where a.c1 = b.c2;
JOIN
SQL 在查询多个表中的数据时,除了可以使用多表查询,还可以使用 join 来进行查询。
上面多表查询的 SQL 与这条 SQL 是等价的:
select a.c1, b.c2 from table1 as a inner join table2 as b on a.c1 = b.c2;
join 除了有 inner join 之外(inner join 与 join 等价),在上面的查询中,table1 称之为左表,table2 称之为右表。join 比多表关联查询功能强大的地方在于 join 可以根据需要,返回不同的结果。
类型 | 备注 |
---|---|
JOIN (INNER JOIN) | 只返回表中匹配的记录 |
LEFT JOIN (LEFT OUTER JOIN) | 即使右表中没有匹配的记录,也会将左表的所有记录返回 |
RIGHT JOIN (RIGHT OUTER JOIN) | 即使左表中没有记录,也会将右表中所有的记录返回 |
FULL JOIN (FULL OUTER JOIN) | 将两个表中所有的记录都返回 |
UNION
union 用于合并多个 select 的查询结果。使用 union 需要满足以下几个条件:
- 所有的 select 语句必须要有相同数量的列
- 每列的数据类型必须一致
- 所有列的排列顺序都需要相同
列名不需要一致
select c1, c2 from table1
union
select c3,c4 from table2;
直接使用 union 返回的结果中不包含重复列,如果需要返回全部的结果,可以使用 UNION ALL。
DDL 基础
SELECT INTO
select into 可以用来创建表的备份,可以配合 where 、JOIN 等语句一起使用。
select * into new_table from lod_table where c1 = v1;
select into 直接使用是在同一个数据库操作,也可以通过 in 来实现跨数据库操作:
select * into new_table in new_datebase from old_table where c1 = v1;
MySQL 不支持 SELECT INTO
CREATE DATABASE
create database 用于创建数据库,使用起来很简单。
create database database_name;
删除数据库:
drop database database_name;
CREATE TABLE
create table 用于创建数据库表。
create table table_name {
c1 datatype,
c2 datatype,
c3 datatype
}
其中 datatype 是 SQL 支持的数据类型。
上面的 SQL 展示了如何创建一个基本的数据库表,但是实际使用的过程中,创建数据表的语句不会这么简单,通常来说会给数据库中的列加上各种各样的约束来满足需要,下表是 SQL 支持的几种约束。
约束 | 备注 |
---|---|
NOT NULL | 列不能为 NULL,主键通常不能为 NULL |
UNIQUE | 列的值在该表中唯一 |
PRIMARY KEY | 数据的主键,在该表中也是唯一 |
FOREIGN KEY | 数据的外键,通常是其他表中数据的主键 |
CHECK | 对某列数据的值加以限制 |
DEFAULT | 给某列数据设定默认值 |
AUTO_INCREMENT | 加上了该约束的列的值会自增 |
not null 就是标识一个字段不能为 null,通常在建表时指定:
create table table_name {
c1 datatype not null,
c2 datatype,
c3 datatype
}
unique 指定每条记录的唯一标识,每个表可以用多个 unique 标识。
create table table_name {
c1 datatype not null,
c2 datatype,
c3 datatype,
unique(c1)
}
也可以把多个字段组合成为唯一标识:
create table table_name {
c1 datatype not null,
c2 datatype,
c3 datatype,
constraint uc_c1_c2 unique (c1, c2)
}
对于已经创建的表添加 unique 约束以及删除现有的约束可以使用 alter table 来进行修改。
删除表:
drop table table_name;
清除表中数据但是不删除表:
truncate table table_name;
ALTER TBALE
使用 alter table 可以增加和删除表的字段,也可以修改字段的类型。
增加字段:
alter table table_name add c1 datatype;
删除字段(有些数据库不允许这个操作):
alter table table_name drop column c1;
修改表中字段的数据类型:
alter table table_name
alter column c1 datatype;
INDEX
在表中可以创建 index,以便更快更高效的查询数据。但是凡事都有代价,增加了索引的表在更新数据的时候会更慢。所以只会在经常被搜索的列和表上创建索引。
创建一个索引,与 unique 一样,可以为一个字段创建一个索引,也可以为多个字段创建一个索引:
create index index_name on table_name (c1);
上面创建的这个索引的值是可以重复的,也可以创建唯一索引,唯一索引的值是不能重复的:
create unique index index_name on table_name (c1);
删除索引(MySQL):
alter table table_name drop index index_name;
VIEW
view 是基于 SQL 语句的结果集的可视化的表,也就是说,视图是一个 SQL 查询结果的集合,视图的结构和表一样,但是其中的字段数据一般来自于多个表。
创建一个视图:
create view view_name as
select a.c1, b.c2 from table1 as a, table2 as b
where a.c1 = b.c2;
然后可以在这个视图中进行查询:
select * from view_name;
删除视图:
drop view view_name
DCL 基础
DCL 用于控制数据库中的授权和事务。
GRANT
给 user1 在 table1 上赋予 select 和 update 的权限。
grant privilege [select, update] on table1 [user1]
TRANSACTION
事务处理严格来说是 RDBMS 的功能,事务用来确保一组 SQL 要么全部执行,要么全部不执行。
主要就是利用 COMMIT 来提交一个事务,利用 ROLLBACK 来回滚一个事务。
SQL 函数
除了基本的 SQL 语法外,SQL 中还有很重要的一个部分就是函数。
函数可以分成两类:
- 聚合查询函数:操作一系列的值,然后返回单一的值
- 标量查询函数:操作一个单一的值,并且返回一个单独的值
函数的使用方式:
select function(c1) form table1;
基本上所有的函数都是这样使用的,但是有一点需要注意的是,如果聚合查询函数在和普通字段一起查询时,一定要加上 group by 关键字。
select c1 , max(c2) from table1 group by c1;
如果有时候我们需要把聚合查询函数作为一个条件来进行查询,但是聚合函数是不能和 where 一起配合使用的,这个时候就需要使用 having。
select c1, max(c2) from table1 having max(c2) > v2;
也可以在函数查询上使用别名:
select c1, max(c2) as m1 from table1 where c1 > v1;
常见聚合函数:
函数 | 备注 |
---|---|
avg | 返回某列的平均值 |
count | 返回某列的行数 |
max | 返回某列的最高值 |
min | 返回某列的最小值 |
常见的标量函数:
函数 | 备注 |
---|---|
format(v, format) | 格式化某列的显示方式 |
now | 返回当前的系统时间 |
len | 返回某列文本的长度 |
SQL 中的数据类型
SQL 是一种编程语言,自然也有其支持的数据类型。在不同的数据库中,数据类型的差异很大。在这里使用 MySQL 的数据类型为例来说明 SQL 中的数据类型。
数据类型 | 备注 |
---|---|
CHAR(size) | 保存固定长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的长度。最多 255 个字符。 |
VARCHAR(size) | 保存可变长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的最大长度。最多 255 个字符。注释:如果值的长度大于 255,则被转换为 TEXT 类型。 |
TINYTEXT | 存放最大长度为 255 个字符的字符串。 |
TEXT | 存放最大长度为 65,535 个字符的字符串。 |
BLOB | 用于 BLOBs (Binary Large OBjects)。存放最多 65,535 字节的数据。 |
MEDIUMTEXT | 存放最大长度为 16,777,215 个字符的字符串。 |
MEDIUMBLOB | 用于 BLOBs (Binary Large OBjects)。存放最多 16,777,215 字节的数据。 |
LONGTEXT | 存放最大长度为 4,294,967,295 个字符的字符串。 |
LONGBLOB | 用于 BLOBs (Binary Large OBjects)。存放最多 4,294,967,295 字节的数据。 |
ENUM(x,y,z,etc.) | 允许你输入可能值的列表。可以在 ENUM 列表中列出最大 65535 个值。如果列表中不存在插入的值,则插入空值。注释:这些值是按照你输入的顺序存储的。可以按照此格式输入可能的值:ENUM(‘X’,‘Y’,‘Z’) |
SET | 与 ENUM 类似,SET 最多只能包含 64 个列表项,不过 SET 可存储一个以上的值。 |
TINYINT(size) | -128 到 127 常规。0 到 255 无符号整数。在括号中规定最大位数。 |
SMALLINT(size) | -32768 到 32767 常规。0 到 65535 无符号整数。在括号中规定最大位数。 |
MEDIUMINT(size) | -8388608 到 8388607 普通。0 to 16777215 无符号整数。在括号中规定最大位数。 |
INT(size) | -2147483648 到 2147483647 常规。0 到 4294967295 无符号整数。在括号中规定最大位数。 |
BIGINT(size) | -9223372036854775808 到 9223372036854775807 常规。0 到 18446744073709551615 无符号整数。在括号中规定最大位数。 |
FLOAT(size,d) | 带有浮动小数点的小数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。 |
DOUBLE(size,d) | 带有浮动小数点的大数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。 |
DECIMAL(size,d) | 作为字符串存储的 DOUBLE 类型,允许固定的小数点。 |
DATE() | 日期。格式:YYYY-MM-DD注释:支持的范围是从 ‘1000-01-01’ 到 ‘9999-12-31’ |
DATETIME() | 日期和时间的组合。格式:YYYY-MM-DD HH:MM:SS注释:支持的范围是从 ‘1000-01-01 00:00:00’ 到 ‘9999-12-31 23:59:59’ |
TIMESTAMP() | 时间戳。TIMESTAMP 值使用 Unix 纪元(‘1970-01-01 00:00:00’ UTC) 至今的描述来存储。格式:YYYY-MM-DD HH:MM:SS注释:支持的范围是从 ‘1970-01-01 00:00:01’ UTC 到 ‘2038-01-09 03:14:07’ UTC |
TIME() | 时间。格式:HH:MM:SS 注释:支持的范围是从 ‘-838:59:59’ 到 ‘838:59:59’ |
YEAR() | 2 位或 4 位格式的年。注释:4 位格式所允许的值:1901 到 2155。2 位格式所允许的值:70 到 69,表示从 1970 到 2069。 |
(完)
- http://www.w3school.com.cn/sql
- MySQL必知必会(第四版)
- 高性能MySQL(第三版)