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 用于从数据库中查询数据。 有两种使用方式,一种是将表中的全部查询出来,一种只查询出来指定的列。 查询全部列:

1
select * from table_name

查询指定列:

1
select c1, c2, c3 from table_name

在返回的数据中,有些列的值是重复的,可以使用 distinct 来返回一列的唯一值:

1
select distinct c2 from table_name

如果需要在查询的的过程中加入条件,那就需要使用 where 来指定查询条件:

1
select * from table_name where c1 = v1;

where 支持的运算符如下:

运算符 描述
= 等于
<> 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
BETWEEN 在某个范围内
LIKE 模糊查询

假如说不止一个条件,可以使用 ANDOR 来连接多个 条件,AND 和 OR 可以组合使用。

1
select * from table_name where c1 = v1 and  c2 = v2 or  c3 <> v3;

使用 select 查询出来的结果的顺序可能不是想要的,那么就可以使用 ORDER BY 来对结果进行排序,order by 默认使用的是升序排序。

使用 desc 来进行降序排序:

1
select * form table_name where c1 = v1 order by c1 desc;

对多个字段使用 order by:

1
select * from table_name where c1 = v1 order by c1, c2;

对不同的字段使用不同的排序规则:

1
select * from table_name where c1 = v1 order by c1 asc, c2 desc;

INSERT INTO

insert into 用于向数据库中插入数据。 两种使用方式,一种是直接插入表中,不指定列,这样需要为每一列都填充数据,否则会报错:

1
insert into table_name values (v1, v2, v3, v4);

也可以指定列:

1
insert into table_name (c2, c3, c4) values (v2, v3, v4);

UPDATE

update 用于更新数据,在更新数据的时候也可以使用 where 来限定某些条件的数据可以被更新。

1
update table_name set c1 = v1 where c1 = v;

DELETE

delete 用于删除表中的数据,可以使用 where 删除限定的数据,也可以删除全部数据。

1
delete from table_name where c1 = v1;

删除全部数据:

1
delete from table_name;

SELECT TOP

用于返回指定的记录的条数:

1
select top 2 * from table_name;

但是这个特性在有的数据库中不支持,但是有相应的替代方案可以选择,在 MySQL 中可以这样实现:

1
select * from table_name limit 2

LIKE like 用于 where 子句中进行模糊查询。

表示查询 c1 列以 bar 开头的记录。

1
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 子句中在固定范围的内进行查询:

1
select * from table_name where c1 in (v1, v2, v3);

BETWEEN AND

between and 可以在 where 子句中指定查询的范围。

1
select * from table_name where c1 between v1 and v2;

between and 同样可以使用 not 来表示查询不在这个范围内的数据,用法如下:

1
select * from table_name where c1 not between v1 and v2;

between and 在不同的数据库中有不同的表现

ALIAS

在 SQL 进行查询的过程中,可以为列名表名都增加别名。

为列增加别名:

1
select c1 as c1_alias from table_name;

为表增加别名:

1
select * from table_name as table_name_alias;

多表查询

SQL 支持同时查询多个表。

1
select a.c1,b.c2 from table1 as a, table2 as b where a.c1 = b.c2;

JOIN

SQL 在查询多个表中的数据时,除了可以使用多表查询,还可以使用 join 来进行查询。

上面多表查询的 SQL 与这条 SQL 是等价的:

1
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 语句必须要有相同数量的列
  • 每列的数据类型必须一致
  • 所有列的排列顺序都需要相同

列名不需要一致

1
2
3
select c1, c2 from table1 
union
select c3,c4 from table2;

直接使用 union 返回的结果中不包含重复列,如果需要返回全部的结果,可以使用 UNION ALL

DDL 基础

SELECT INTO

select into 可以用来创建表的备份,可以配合 where 、JOIN 等语句一起使用。

1
select * into new_table from lod_table where c1 = v1;

select into 直接使用是在同一个数据库操作,也可以通过 in 来实现跨数据库操作:

1
select * into new_table in new_datebase from old_table where c1 = v1;

MySQL 不支持 SELECT INTO

CREATE DATABASE

create database 用于创建数据库,使用起来很简单。

1
create database database_name;

删除数据库:

1
drop database database_name;

CREATE TABLE

create table 用于创建数据库表。

1
2
3
4
5
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,通常在建表时指定:

1
2
3
4
5
create table table_name {
c1 datatype not null,
c2 datatype,
c3 datatype
}

unique 指定每条记录的唯一标识,每个表可以用多个 unique 标识。

1
2
3
4
5
6
create table table_name {
c1 datatype not null,
c2 datatype,
c3 datatype,
unique(c1)
}

也可以把多个字段组合成为唯一标识:

1
2
3
4
5
6
create table table_name {
c1 datatype not null,
c2 datatype,
c3 datatype,
constraint uc_c1_c2 unique (c1, c2)
}

对于已经创建的表添加 unique 约束以及删除现有的约束可以使用 alter table 来进行修改。

删除表:

1
drop table table_name;

清除表中数据但是不删除表:

1
truncate table table_name;

ALTER TBALE

使用 alter table 可以增加和删除表的字段,也可以修改字段的类型。

增加字段:

1
alter table table_name add c1 datatype;

删除字段(有些数据库不允许这个操作):

1
alter table table_name drop column c1;

修改表中字段的数据类型:

1
2
alter table table_name
alter column c1 datatype;

INDEX

在表中可以创建 index,以便更快更高效的查询数据。但是凡事都有代价,增加了索引的表在更新数据的时候会更慢。所以只会在经常被搜索的列和表上创建索引。

创建一个索引,与 unique 一样,可以为一个字段创建一个索引,也可以为多个字段创建一个索引:

1
create index index_name on table_name (c1);

上面创建的这个索引的值是可以重复的,也可以创建唯一索引,唯一索引的值是不能重复的:

1
create unique index index_name on table_name (c1);

删除索引(MySQL):

1
alter table table_name drop index index_name;

VIEW

view 是基于 SQL 语句的结果集的可视化的表,也就是说,视图是一个 SQL 查询结果的集合,视图的结构和表一样,但是其中的字段数据一般来自于多个表。

创建一个视图:

1
2
3
create view view_name as
select a.c1, b.c2 from table1 as a, table2 as b
where a.c1 = b.c2;

然后可以在这个视图中进行查询:

1
select * from view_name;

删除视图:

1
drop view view_name

DCL 基础

DCL 用于控制数据库中的授权和事务。

GRANT

给 user1 在 table1 上赋予 select 和 update 的权限。

1
grant privilege [select, update] on table1 [user1]

TRANSACTION

事务处理严格来说是 RDBMS 的功能,事务用来确保一组 SQL 要么全部执行,要么全部不执行。

主要就是利用 COMMIT 来提交一个事务,利用 ROLLBACK 来回滚一个事务。

SQL 函数

除了基本的 SQL 语法外,SQL 中还有很重要的一个部分就是函数

函数可以分成两类:

  • 聚合查询函数:操作一系列的值,然后返回单一的值
  • 标量查询函数:操作一个单一的值,并且返回一个单独的值

函数的使用方式:

1
select function(c1) form table1;

基本上所有的函数都是这样使用的,但是有一点需要注意的是,如果聚合查询函数在和普通字段一起查询时,一定要加上 group by 关键字

1
select c1 , max(c2) from table1 group by c1;

如果有时候我们需要把聚合查询函数作为一个条件来进行查询,但是聚合函数是不能和 where 一起配合使用的,这个时候就需要使用 having。

1
select c1, max(c2) from table1 having max(c2) > v2;

也可以在函数查询上使用别名:

1
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。

(完)

  1. http://www.w3school.com.cn/sql
  2. MySQL必知必会(第四版)
  3. 高性能MySQL(第三版)

微信公众号

© 2018 ray