SQL 教程
1、一些重要的SQL命令
| 命令 | 含义 |
|---|---|
| select | 从数据库中提取数据 |
| update | 更新数据库中的数据 |
| delete | 从数据库中删除数据 |
| insert into | 从数据库中插入新数据 |
| create database | 创建新数据库 |
| create table | 创建新表 |
| alter table | 变更数据库表 |
| drop table | 删除表 |
| create index | 创建索引 |
| drop index | 删除索引 |
2、distinct
一个列可能包含多个重复值,distinct用于返回唯一不同的值(去重)。
select distinct column1, column2, ... from table_name;
3、where子句中的运算符
| 运算符 | 描述 |
|---|---|
| = | 等于 |
| <> | 不等于 |
| >= | 大于等于 |
| <= | 小于等于 |
| BETWEEN | 在某个范围内 |
| LIKE | 搜索某种模式 |
| IN | 指定针对某个列的多个可能值 |
4、order by
- ORDER BY 用于对结果集按照一个列或者多个列进行排序。
- ORDER BY 关键字默认升序(ASC,可省略),降序为DESC。
order by多列:
select * from table_name order by column1 desc, column2 desc;
5、insert into
第一种形式无需指定要插入数据的列名,只需提供被插入的值即可:
INSERT INTO table_name
VALUES (value1,value2,value3,...);
第二种形式需要指定列名及被插入的值:
INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
6、update
update应用于更新表中已存在的记录。
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
7、delete
delete语句用于删除表中的行。
DELETE FROM table_name
WHERE condition;
SQL高级
1、SQL通配符
在SQL中,通配符与SQL LIKE操作符一起使用。
| 通配符 | 描述 |
|---|---|
| % | 替换0个或多个字符 |
| _ | 替换一个字符 |
| [charlist] | 字符列中的任何单一字符 |
| [^charlist] 或 [!charlist] | 不在字符列中的任何单一字符 |
MySQL 中使用 REGEXP 或 NOT REGEXP 运算符 (或 RLIKE 和 NOT RLIKE) 来操作正则表达式。
- 选取 url 以字母 "https" 开始的所有网站:
SELECT * FROM Websites WHERE url LIKE 'https%';
- 选取 url 包含模式 "oo" 的所有网站:
SELECT * FROM Websites
WHERE url LIKE '%oo%';
- 选取 name 以一个任意字符开始,然后是 "oogle" 的所有客户:
SELECT * FROM Websites
WHERE name LIKE '_oogle';
- 选取 name 以 "G" 开始,然后是一个任意字符,然后是 "o",然后是一个任意字符,然后是 "le" 的所有网站:
SELECT * FROM Websites
WHERE name LIKE 'G_o_le';
- 选取 name 以 "G"、"F" 或 "s" 开始的所有网站:
SELECT * FROM Websites
WHERE name REGEXP '^[GFs]';
- 选取 name 以 A 到 H 字母开头的网站:
SELECT * FROM Websites
WHERE name REGEXP '^[A-H]';
- 选取 name 不以 A 到 H 字母开头的网站:
SELECT * FROM Websites
WHERE name REGEXP '^[^A-H]';
2、in、between
in操作符允许你在where子句中规定多个值。
SELECT column1, column2, ...
FROM table_name
WHERE column IN (value1, value2, ...);
between操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
SELECT column1, column2, ...
FROM table_name
WHERE column BETWEEN value1 AND value2;
在MySQL中,between and 能匹配指定范围内的所有值,包括起始值和终止值。
3、别名
通过使用 SQL,可以为表名称或列名称指定别名。(指定别名AS可省略)
列的 SQL 别名语法
SELECT column_name AS alias_name
FROM table_name;
表的 SQL 别名语法
SELECT column_name(s)
FROM table_name AS alias_name;
4、join及其延伸
下图展示了left join、right join、inner join、outer join相关的7种用法。
join语法:
SELECT column1, column2, ...
FROM table1
JOIN table2 ON condition;
- INNER JOIN:如果表中有至少一个匹配,则返回行
- LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行(在某些数据库中,LEFT JOIN 称为 LEFT OUTER JOIN)
- RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行(在某些数据库中,RIGHT JOIN 称为 RIGHT OUTER JOIN)
- FULL JOIN:只要其中一个表中存在匹配,则返回行(FULL OUTER JOIN ,结合了 LEFT JOIN 和 RIGHT JOIN 的结果)
5、union
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法:
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法:
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
6、insert into select
INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响。
我们可以从一个表中复制所有的列插入到另一个已存在的表中:
INSERT INTO table2
SELECT * FROM table1;
或者我们可以只复制指定的列插入到另一个已存在的表中:
INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;
7、create database/table
CREATE DATABASE 语句用于创建数据库。
CREATE DATABASE dbname;
CREATE TABLE 语句用于创建数据库中的表。表由行和列组成。
CREATE TABLE table_name
(
column_name1 data_type(size),
column_name2 data_type(size),
column_name3 data_type(size),
....
);
8、NOT NULL
NOT NULL 约束强制列不接受 NULL 值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。
在一个已创建的表的“Age”字段添加NOT NULL约束:
ALTER TABLE Persons
MODIFY Age int NOT NULL;
在一个已创建的表的“Age”字段删除NOT NULL约束:
ALTER TABLE Persons
MODIFY Age int NULL;
9、unique、primary
- UNIQUE 约束唯一标识数据库表中的每条记录。
- UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。
- PRIMARY KEY 约束拥有自动定义的 UNIQUE 约束。
- 请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。
10、foreign key
- 一个表中的 FOREIGN KEY 指向另一个表中的 UNIQUE KEY(唯一约束的键)。
- FOREIGN KEY 约束用于预防破坏表之间连接的行为。
- FOREIGN KEY 约束也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
11、check
- CHECK 约束用于限制列中的值的范围。
- 如果对单个列定义 CHECK 约束,那么该列只允许特定的值。
- 如果对一个表定义 CHECK 约束,那么此约束会基于行中其他列的值在特定的列中对值进行限制。
12、default
- DEFAULT 约束用于向列中插入默认值。
- 如果没有规定其他的值,那么会将默认值添加到所有的新记录。
13、index
- CREATE INDEX 语句用于在表中创建索引。
- 在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。
在表上创建一个简单的索引。允许使用重复的值:
CREATE INDEX index_name
ON table_name (column_name)
14、drop
通过使用 DROP 语句,可以轻松地删除索引、表和数据库。
用于 MySQL 的 DROP INDEX 语法:
ALTER TABLE table_name DROP INDEX index_name
DROP TABLE 语句用于删除表。
DROP TABLE table_name
DROP DATABASE 语句用于删除数据库。
DROP DATABASE database_name
如果我们仅仅需要删除表内的数据,但并不删除表本身,那么我们该如何做呢?——请使用 TRUNCATE TABLE 语句:
TRUNCATE TABLE table_name
15、alter table
ALTER TABLE 语句用于在已有的表中添加、删除或修改列。
16、SQL日期
SQL Date 数据类型
MySQL 使用下列数据类型在数据库中存储日期或日期/时间值:
- DATE - 格式:YYYY-MM-DD
- DATETIME - 格式:YYYY-MM-DD HH:MM:SS
- TIMESTAMP - 格式:YYYY-MM-DD HH:MM:SS
- YEAR - 格式:YYYY 或 YY
SQL Server 使用下列数据类型在数据库中存储日期或日期/时间值:
- DATE - 格式:YYYY-MM-DD
- DATETIME - 格式:YYYY-MM-DD HH:MM:SS
- SMALLDATETIME - 格式:YYYY-MM-DD HH:MM:SS
- TIMESTAMP - 格式:唯一的数字
注释: 当您在数据库中创建一个新表时,需要为列选择数据类型!
17、NULL值
默认地,表的列可以存放 NULL 值。NULL 用作未知的或不适用的值的占位符。
注释: 无法比较 NULL 和 0;它们是不等价的。
那么我们如何测试 NULL 值呢?——无法使用比较运算符来测试 NULL 值,比如 =、< 或 <>。我们必须使用 IS NULL 和 IS NOT NULL 操作符。
SELECT LastName,FirstName,Address FROM Persons
WHERE Address IS (NOT) NULL;
SQL函数
1、avg、count
AVG() 函数返回数值列的平均值。
AVG() 语法:
SELECT AVG(column_name) FROM table_name;
COUNT() 函数返回匹配指定条件的行数。
COUNT(column_name) 函数返回指定列的值的数目(NULL 不计入):
SELECT COUNT(column_name) FROM table_name;
COUNT(*) 函数返回表中的记录数:
SELECT COUNT(*) FROM table_name;
COUNT(DISTINCT column_name) 函数返回指定列的不同值的数目:
SELECT COUNT(DISTINCT column_name) FROM table_name;
注释: COUNT(DISTINCT) 适用于 Oracle 和 Microsoft SQL Server,但是无法用于 Microsoft Access。
2、first、last
- FIRST() 函数返回指定的列中第一个记录的值。
- LAST() 函数返回指定的列中最后一个记录的值。
SQL FIRST()、LAST() 语法:
SELECT FIRST(column_name) FROM table_name;
SELECT LAST(column_name) FROM table_name;
注释:只有 MS Access 支持 FIRST()、LAST() 函数。
- 选取 "Websites" 表的 "name" 列中第一个记录的值:
SELECT name AS FirstSite FROM Websites LIMIT 1; - 选取 "Websites" 表的 "name" 列中最后一个记录的值:
SELECT name FROM Websites ORDER BY id DESC LIMIT 1;
3、max、min、sum
- MAX() 函数返回指定列的最大值。
- MIN() 函数返回指定列的最小值。
- SUM() 函数返回数值列的总数。
SQL语法:
SELECT MAX(column_name) FROM table_name;
SELECT MIN(column_name) FROM table_name;
SELECT SUM(column_name) FROM table_name;
4、group by
GROUP BY 语句用于结合聚合函数,根据一个或多个列对结果集进行分组。
(多表查询实例:)统计有记录的网站的记录数量:
SELECT Websites.name,COUNT(access_log.aid) AS nums FROM access_log
LEFT JOIN Websites
ON access_log.site_id=Websites.id
GROUP BY Websites.name;
5、having
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。HAVING 子句可以让我们筛选分组后的各组数据。
SQL HAVING 语法
SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value;
实例:查找总访问量大于 200 的网站
SELECT Websites.name, Websites.url, SUM(access_log.count) AS nums FROM (access_log
INNER JOIN Websites
ON access_log.site_id=Websites.id)
GROUP BY Websites.name
HAVING SUM(access_log.count) > 200;
where 和having之后都是筛选条件,但是有区别的:
- where在group by前, having在group by 之后
- 聚合函数(avg、sum、max、min、count),不能作为条件放在where之后,但可以放在having之后
6、exists
EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False。
SQL EXISTS 语法:
SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);
7、ucase()、lcase()
- UCASE() 函数把字段的值转换为大写。
- LCASE() 函数把字段的值转换为小写。
SQL UCASE()/LCASE() 语法:
SELECT UCASE(column_name) FROM table_name;
SELECT LCASE(column_name) FROM table_name;
用于 SQL Server 的语法:
SELECT UPPER(column_name) FROM table_name;
SELECT LOWER(column_name) FROM table_name;
8、mid()
MID() 函数用于从文本字段中提取字符。
SELECT MID(column_name[,start,length]) FROM table_name;
实例:从 "Websites" 表的 "name" 列中提取前 4 个字符:
SELECT MID(name,1,4) AS ShortTitle
FROM Websites;
| 参数 | 描述 |
|---|---|
| column_name | 必需。要提取字符的字段 |
| start | 必需。规定开始位置(起始值是 1) |
| length | 可选。要返回的字符数。如果省略,则 MID()函数返回剩余文本 |
9、len()
LEN() 函数返回文本字段中值的长度。
SQL LEN() 语法
SELECT LEN(column_name) FROM table_name;
MySQL 中函数为 LENGTH():
SELECT LENGTH(column_name) FROM table_name;
10、round()
- ROUND() 函数用于把数值字段舍入为指定的小数位数。
- ROUND(X):返回参数X的四舍五入的一个整数。
- ROUND(X,D):返回参数X的四舍五入的有 D 位小数的一个数字。如果D为0,结果将没有小数点或小数部分。
SELECT ROUND(column_name,decimals) FROM TABLE_NAME;
| 参数 | 描述 |
|---|---|
| column_name | 必需。要舍入的字段 |
| decimals | 可选。规定要返回的小数位数 |
11、now()
NOW() 函数返回当前系统的日期和时间。
SELECT NOW() FROM table_name;
12、format()
FORMAT() 函数用于对字段的显示进行格式化。
SQL FORMAT() 语法
SELECT FORMAT(column_name,format) FROM table_name;
| 参数 | 描述 |
|---|---|
| column_name | 必需。要格式化的字段 |
| format | 必需。规定格式 |
SQL FORMAT() 实例:从 "Websites" 表中选取 name, url 以及格式化为 YYYY-MM-DD 的日期:
SELECT name, url, DATE_FORMAT(Now(),'%Y-%m-%d') AS date
FROM Websites;