参考来源
此外建议:配合nowcoder、leetcode 进行相关代码训练,学习效果更佳。
SQL 语言学习-来源于菜鸟教程
- SQL 教程
- SQL 高级教程
- SQL select top , limit , rownum 子句
- SQL like & [通配符](https://www.runoob.com/sql/sql-wildcards.html)
- SQL in
- SQL between
- SQL 别名 as
- SQL 连接 (join)
- SQL union
- SQL select into [重点:MySQL 不支持]
- SQL insert into select
- SQL create database
- SQL create table 约束 / not null / unique / primary key / foreign key / check / default
- SQL create index
- SQL drop
- SQL alter
- SQL auto increment
- SQL 视图
- SQL 日期
- 处理日期时,最难SQL Date 数据类型
- SQL null 值
- SQL null 函数
- SQL 通用数据类型
- SQL DB 数据类型
- SQL 函数
SQL 教程
SQL 是用于访问和处理数据库的标准计算机语言。
通过笔记和菜鸟教程快速学习如何使用 SQL 访问和处理数据系统中的数据,这类数据库包括:MySQL、SQL Server、Access、Oracle、Sybase、DB2等等。
SQL 简介
- SQL 是什么?
- SQL 指结构化查询语言,全称是Structured Query Language。
- SQL 实现访问和处理数据库能力,包括数据插入、查询、更新和删除。
- SQL 在1986 年成为 ANSI 的一项标准,在 1987 年成为国际标准组织 (ISO) 标准。1
- SQL 能做什么?
- SQL 面向数据库执行查询
- SQL 可从数据库取回数据
- SQL 可在数据库中插入新的记录
- SQL 可更新数据库中的数据
- … 删除数据
- SQL 可创建新数据库
- SQL 可在数据库中创建新表
- SQL 可在数据库中创建存储过程
- SQL 可在数据库中创建视图
- SQL 可设置表、存储过程和视图的权限
- 要创建一个显示数据库中数据的网站,需要:
- RDBMS2 数据库程序 (如: MS Access、SQL Server、MySQL)
- 使用服务器端脚本语言,比如 PHP 或 ASP
- 使用 SQL 来获取想要的数据
- 使用 HTML/CSS
SQL 语法
- 数据库表
一个数据库通常包含一个或多个表。这里使用的参考表为;
id | name | url | alexa | country |
---|---|---|---|---|
1 | https://www.google.cm/ | 1 | USA | |
2 | 淘宝 | https://www.taobao.com/ | 13 | CN |
3 | 菜鸟教程 | http://www.runoob.com/ | 4689 | CN |
4 | 微博 | http://weibo.com/ | 20 | CN |
5 | https://www.facebook.com/ | 3 | USA |
mysql> use RUNOOB ; # 选择数据库
mysql> set names utf8 ; # 用于设置使用的字符集
mysql> select * from Websites ; # 读取数据表的信息
- SQL 对大小写不敏感:SELECT 和 select 是相同的
- SQL 语句后面的分号?
- 某些数据库系统要求在每条 SQL 语句的末端使用分号。
- 分号是数据库系统中分隔每条 SQL 语句的标准方法,这样就可以在对服务器的相同请求中执行一条以上的 SQL 语句。
[这里每条 SQL 语句都使用分号]
- 一些重要的 SQL 命令
命令 | 解释 |
---|---|
select | 从数据库中提取数据 |
update | 更新数据库中的数据 |
delete | 从数据库中删除数据 |
insert into | 向数据库中插入新数据 |
create database | 创建新数据库 |
alter database | 修改数据库 |
create table | 创建新表 |
alter table | 变更数据库表 |
drop table | 删除表 |
create index | 创建索引 (搜索键) |
drop index | 删除索引 |
SQL select / select distinct
SELECT column_name,column_name # column_name 表示要查询的目标
FROM table_name;
SELECT * FROM table_name; # * 表示表中的所有属性
SELECT DISTINCT column_name,column_name # DISTINCT 表示去除重复行
FROM table_name;
SQL where (and or between like 等等)
where
子句用于过滤记录。
# 参考标准
SELECT column_name,column_name
FROM table_name
WHERE column_name operator value;
# 例子
SELECT * FROM Websites WHERE country='CN'; # 如果是数值字段,不要使用引号。如 WHERE id=1;
# 字符串字段使用 '' 单引号; 且区分大小写
- WHERE 子句中的运算符等
运算符 | 描述 |
---|---|
and | 同时满足多个条件 |
or | 满足其中一个条件 |
not | 满足不包含该条件的值 |
逻辑运算的优先级 | () not and or |
特殊条件 is null | mysql> Select * from emp where comm is null; 查询 emp 表中 comm 列中的空值。 |
= | 等于 |
<> | 不等于。注释:在 SQL 的一些版本中,该操作符可被写成 != |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
between | 在某个范围内;包含边界。 |
like | 搜索某种模式。例子: Select * from emp where ename like ‘M%’; 查询 EMP 表中 Ename 列中有 M 的值,M 为要查询内容中的模糊信息。 % 表示多个字值,_ 下划线表示一个字符; M% : 为能配符,正则表达式,表示的意思为模糊查询信息为 M 开头的。 %M% : 表示查询包含M的所有内容。 %M_ : 表示查询以M在倒数第二位的所有内容。 |
in | 指定针对某个列的多个可能值 Select * from emp where sal in (5000,3000,1500); |
SQL order by
order by 关键字用于对结果集按照一个或者多个列进行排序。
order by 关键字默认按照升序进行排序。如果需要按照降序对记录进行排序,使用 desc
关键字
SELECT column_name,column_name
FROM table_name
ORDER BY column_name,column_name ASC|DESC;
order by A,B 这个时候都是默认按升序排列
order by A desc,B 这个时候 A 降序,B 升序排列
order by A ,B desc 这个时候 A 升序,B 降序排列
# MySQL 里分页一般用 LIMIT 来实现:
select* from article LIMIT 1,3
select * from article LIMIT 3 OFFSET 1
# 上面两种写法都表示取 2、3、4 三条条数据:
# 当 LIMIT 后面跟两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量,例如:
# select* from article LIMIT 1,3 就是跳过 1 条数据,从第 2 条数据开始取,取 3 条数据,也就是取 2、3、4 三条数据。
# 当 LIMIT 后面跟一个参数的时候,该参数表示要取的数据的数量。
# 例如 select* from article LIMIT 3 表示直接取前三条数据,类似 sqlserver 里的 top 语法。
# 当 LIMIT 和 OFFSET 组合使用的时候,LIMIT 后面只能有一个参数,表示要取的的数量,OFFSET表示要跳过的数量 。
# 例如 select * from article LIMIT 3 OFFSET 1 表示跳过 1 条数据,从第 2 条数据开始取,取3条数据,也就是取 2、3、4 三条数据。
SQL insert into
insert into
语句用于向表中插入新记录。
- SQL INSERT INTO 语法
INSERT INTO 语句可以有两种编写形式。
第一种形式无需指定要插入数据的列名,只需提供被插入的值即可:
Insert into table_name
values (value1,value2,value3,…);
第二种形式需要指定列名及被插入的值:
Insert into table_name (column1,column2,column3,…)
values (value1,value2,value3,…);
INSERT INTO Websites (name, url, alexa, country)
VALUES ('百度','https://www.baidu.com/','4','CN');
# 没有向 id 字段插入任何数字?
# id 列是自动更新的,表中的每条记录都有一个唯一的数字
# 在指定列插入数据
INSERT INTO Websites (name, url, country)
VALUES ('stackoverflow', 'http://stackoverflow.com/', 'IND');
需要检测:insert into select 和select into from 的区别3。
SQL update
update 语句用于更新表中已存在的记录。
- SQL UPDATE 语法
UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value;
# 实例
UPDATE Websites
SET alexa='5000', country='USA'
WHERE name='菜鸟教程';
注意 SQL UPDATE 语句中的 WHERE 子句!
WHERE 子句规定哪条记录或者哪些记录需要更新。如果省略了 WHERE 子句,所有的记录都将被更新!甚至会报错。
SQL delete
Delete 语句用于删除表中的记录。
- SQL DELETE 语句
Delete 语句用于删除表中的行。
DELETE FROM table_name
WHERE some_column=some_value;
# 实例
DELETE FROM Websites
WHERE name='Facebook' AND country='USA';
注意 SQL DELETE 语句中的 WHERE 子句!
WHERE 子句规定哪条记录或者哪些记录需要删除。如果您省略了 WHERE 子句,所有的记录都将被删除!
-
SQL关于删除的三个语句:DROP、TRUNCATE、 DELETE 的区别。
truncate table 命令将快速删除数据表中的所有记录,但保留数据表结构。这种快速删除与 delete from 数据表的删除全部数据表记录不一样,delete 命令删除的数据将存储在系统回滚段中,需要的时候,数据可以回滚恢复,而 truncate 命令删除的数据是不可以恢复的。-
相同点
truncate 和不带 where 子句的 delete, 以及 drop 都会删除表内的数据。 -
不同点:
- truncate 和 delete 只删除数据不删除表的结构(定义) ,drop 语句将删除表的结构被依赖的约束(constrain), 触发器(trigger), 索引(index); 依赖于该表的存储过程/函数将保留, 但是变为 invalid 状态。
- delete 语句是 dml, 这个操作会放到 rollback segement 中, 事务提交之后才生效; 如果有相应的 trigger, 执行的时候将被触发。 truncate, drop 是 ddl, 操作立即生效, 原数据不放到 rollback segment 中, 不能回滚。 操作不触发 trigger。
- delete 语句不影响表所占用的 extent, 高水线(high watermark)保持原位置不动。 显然 drop 语句将表所占用的空间全部释放 。 truncate 语句缺省情况下见空间释放到 minextents 个 extent, 除非使用 reuse storage; truncate会将高水线复位(回到最开始)。
- 速度:一般来说: drop > truncate > delete 。
- 安全性: 小心使用 drop 和 truncate, 尤其没有备份的时候。否则哭都来不及。
-
使用上, 想删除部分数据行用 delete, 注意带上 where 子句。 回滚段要足够大。
想删除表, 当然用 drop。
想保留表而将所有数据删除。如果和事务无关, 用 truncate 即可。 如果和事务有关, 或者想触发 trigger, 还是用 delete。
如果是整理表内部的碎片, 可以用 truncate 跟上 reuse stroage, 再重新导入/插入数据。
DROP test; # 删除表test,并释放空间,将test删除的一干二净。
TRUNCATE test; # 删除表test里的内容,并释放空间,但不删除表的定义,表的结构还在。
DELETE FROM test 或者 DELETE FROM test; # 仅删除表test内的所有内容,保留表的定义,不释放空间。
DELETE * FROM test 或者 DELETE * FROM test;
安装模式设置:
set sql_safe_updates=1; # 安全模式打开状态
set sql_safe_updates=0; # 安全模式关闭状态
SQL 高级教程
SQL select top , limit , rownum 子句
select top 子句用于规定要返回的记录的数目。
select top 子句对于拥有数千条记录的大型表来说,是非常有用的。
注意:并非所有的数据库系统都支持 select top 语句。 MySQL 支持 limit 语句来选取指定的条数数据, Oracle 可以使用 ROWNUM 来选取。
# SQL Server / MS Access 语法
SELECT TOP number|percent column_name(s)
FROM table_name;
# MySQL 语法
SELECT column_name(s)
FROM table_name
LIMIT number;
# 实例
SELECT *
FROM Persons
LIMIT 5;
# Oracle 语法
SELECT column_name(s)
FROM table_name
WHERE ROWNUM <= number;
# 实例
SELECT *
FROM Persons
WHERE ROWNUM <=5;
SQL like & 通配符
like 操作符用于在 where 子句中搜索列中的指定模式。
- SQL like 语法
SELECT column_name(s)
FROM table_name
WHERE column_name LIKE pattern;
'%a' # 以a结尾的数据
'a%' # 以a开头的数据
'%a%' # 含有a的数据
‘\_a\_’ # 三位且中间字母是a的
'\_a' # 两位且结尾字母是a的
'a\_' # 两位且开头字母是a的
通配符 | 描述 |
---|---|
% | 替代 0 个或多个字符 |
_ | 替代一个字符 |
[charlist] | 字符列中的任何单一字符 |
[ ^charlist] 或 [!charlist] | 不在字符列中的任何单一字符 |
SQL 中,通配符与 SQL LIKE 操作符一起使用。
不过,MySQL 、SQLite 只支持 % 和 _ 通配符,不支持 [^charlist] 或 [!charlist] 通配符( MS Access 支持,微软 office 对通配符一直支持良好,但微软有时候的通配符不支持 %,而是 *,具体看对应软件说明)。通配符和正则不是一回事。
MySQL 和 SQLite 会把 like ‘[xxx]yyy’ 的中括号当成普通字符,而不是通配符。
# 使用 SQL [charlist] 通配符
# MySQL 中使用 REGEXP 或 NOT REGEXP 运算符 (或 RLIKE 和 NOT RLIKE) 来操作正则表达式。
# 下面的 SQL 语句选取 name 以 "G"、"F" 或 "s" 开始的所有网站:
SELECT * FROM Websites
WHERE name REGEXP '^[GFs]';
# 下面的 SQL 语句选取 name 以 A 到 H 字母开头的网站:
SELECT * FROM Websites
WHERE name REGEXP '^[A-H]';
# 下面的 SQL 语句选取 name 不以 A 到 H 字母开头的网站:
SELECT * FROM Websites
WHERE name REGEXP '^[^A-H]';
SQL in
in 操作符允许您在 where 子句中规定多个值。
- SQL in 语法
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,…);
# IN 操作符实例
# 下面的 SQL 语句选取 name 为 "Google" 或 "菜鸟教程" 的所有网站:
SELECT * FROM Websites
WHERE name IN ('Google','菜鸟教程');
SQL between
between 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
- SQL between 语法
SELECT column_name(s)
FROM table_name
WHERE column_name BETWEEN value1 AND value2;
# BETWEEN 操作符实例
# 下面的 SQL 语句选取 alexa 介于 1 和 20 之间的所有网站:
SELECT * FROM Websites
WHERE alexa BETWEEN 1 AND 20;
# 如需显示不在上面实例范围内的网站,请使用 NOT BETWEEN:
SELECT * FROM Websites
WHERE alexa NOT BETWEEN 1 AND 20;
#带有 IN 的 BETWEEN 操作符实例
#下面的 SQL 语句选取 alexa 介于 1 和 20 之间但 country 不为 USA 和 IND 的所有网站:
SELECT * FROM Websites
WHERE (alexa BETWEEN 1 AND 20)
AND country NOT IN ('USA', 'IND');
# 带有文本值的 BETWEEN 操作符实例
# 下面的 SQL 语句选取 name 以介于 'A' 和 'H' 之间字母开始的所有网站:
SELECT * FROM Websites
WHERE name BETWEEN 'A' AND 'H';
# 带有文本值的 NOT BETWEEN 操作符实例
# 下面的 SQL 语句选取 name 不介于 'A' 和 'H' 之间字母开始的所有网站:
SELECT * FROM Websites
WHERE name NOT BETWEEN 'A' AND 'H';
# 带有日期值的 BETWEEN 操作符实例
# 下面的 SQL 语句选取 date 介于 '2016-05-10' 和 '2016-05-14' 之间的所有访问记录:
SELECT * FROM access_log
WHERE date BETWEEN '2016-05-10' AND '2016-05-14';
- 注意 :
在不同的数据库中,BETWEEN 操作符会产生不同的结果!
在某些数据库中,BETWEEN 选取介于两个值之间但不包括两个测试值的字段。( )
在某些数据库中,BETWEEN 选取介于两个值之间且包括两个测试值的字段。[ ]
在某些数据库中,BETWEEN 选取介于两个值之间且包括第一个测试值但不包括最后一个测试值的字段。( ] , [ )
因此,请检查数据库是如何处理 BETWEEN 操作符!
SQL 别名 as
通过使用 SQL,可以为表名称或列名称指定别名。基本上,创建别名是为了让列名称的可读性更强。
# 列的 SQL 别名语法
SELECT column_name AS alias_name
FROM table_name;
# 表的 SQL 别名语法
SELECT column_name(s)
FROM table_name AS alias_name;
# 列的别名实例
# 下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。提示:如果列名称包含空格,要求使用双引号或方括号:
SELECT name AS n, country AS c
FROM Websites;
# 在下面的 SQL 语句中,把三个列(url、alexa 和 country)结合在一起,并创建一个名为 "site_info" 的别名:
SELECT name, concat(url, ', ', alexa, ', ', country) AS site_info
FROM Websites;
# 表的别名实例
# 下面的 SQL 语句选取 "菜鸟教程" 的所有访问记录。使用 "Websites" 和 "access_log" 表,并分别为它们指定表别名 "w" 和 "a"(通过使用别名让 SQL 更简短):
SELECT w.name, w.url, a.count, a.date
FROM Websites AS w, access_log AS a
WHERE a.site_id=w.id and w.name="菜鸟教程";
# 不带别名的相同的 SQL 语句:
SELECT Websites.name, Websites.url, access_log.count, access_log.date
FROM Websites, access_log
WHERE Websites.id=access_log.site_id and Websites.name="菜鸟教程";
在下面的情况下,使用别名很有用:
- 在查询中涉及超过一个表
- 在查询中使用了函数
- 列名称很长或者可读性差
- 需要把两个列或者多个列结合在一起
SQL 连接 (join)
SQL join 用于把来自两个或多个表的行结合起来。
下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。
- SQL join
SQL join 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。最常见的join
类型:SQL inner join(简单的join
)。 SQL inner join 从多个表中返回满足join
条件的所有行。 - SQL inner join 关键字
inner join 关键字在表中存在至少一个匹配时返回行。 - SQL left join 关键字
left join 关键字从左表返回所有的行,即使右表中没有匹配。如果右表中没有匹配,则结果为 NULL。 - SQL right join 关键字
right join 关键字从右表返回所有的行,即使左表中没有匹配。如果左表中没有匹配,则结果为 NULL。 - SQL full outer join 关键字
full outer join 关键字只要左表和右表其中一个表中存在匹配,则返回行.
# "Websites" 表中的 "id" 列指向 "access_log" 表中的字段 "site_id"。上面这两个表是通过 "site_id" 列联系起来的。
# 然后,如果我们运行下面的 SQL 语句(包含 INNER JOIN):
SELECT Websites.id, Websites.name, access_log.count, access_log.date
FROM Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id;
# SQL INNER JOIN 语法
SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name=table2.column_name;
# 或:
SELECT column_name(s)
FROM table1
JOIN table2
ON table1.column_name=table2.column_name;
# 注释:INNER JOIN 与 JOIN 是相同的。
# 实例
SELECT Websites.name, access_log.count, access_log.date
FROM Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id
ORDER BY access_log.count;
# 注释:INNER JOIN 关键字在表中存在至少一个匹配时返回行。如果 "Websites" 表中的行在 "access_log" 中没有匹配,则不会列出这些行。
# SQL LEFT JOIN 语法
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;
# 或:
SELECT column_name(s)
FROM table1
LEFT OUTER JOIN table2
ON table1.column_name=table2.column_name;
# 注释:在某些数据库中,LEFT JOIN 称为 LEFT OUTER JOIN。
# 下面的 SQL 语句将返回所有网站及他们的访问量(如果有的话)。
# 以下实例中把 Websites 作为左表,access_log 作为右表:
# 实例
SELECT Websites.name, access_log.count, access_log.date
FROM Websites
LEFT JOIN access_log
ON Websites.id=access_log.site_id
ORDER BY access_log.count DESC;
# 注释:LEFT JOIN 关键字从左表(Websites)返回所有的行,即使右表(access_log)中没有匹配。
# SQL RIGHT JOIN 语法
SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name;
# 或:
SELECT column_name(s)
FROM table1
RIGHT OUTER JOIN table2
ON table1.column_name=table2.column_name;
# 注释:在某些数据库中,RIGHT JOIN 称为 RIGHT OUTER JOIN。
# 下面的 SQL 语句将返回网站的访问记录。
# 以下实例中我们把 Websites 作为左表,access_log 作为右表:
# 实例
SELECT websites.name, access_log.count, access_log.date
FROM websites
RIGHT JOIN access_log
ON access_log.site_id=websites.id
ORDER BY access_log.count DESC;
# 注释:RIGHT JOIN 关键字从右表(access_log)返回所有的行,即使左表(Websites)中没有匹配。
# SQL FULL OUTER JOIN 语法
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;
# 下面的 SQL 语句选取所有网站访问记录。
# MySQL中不支持 FULL OUTER JOIN,你可以在 SQL Server 测试以下实例。
# 实例
SELECT Websites.name, access_log.count, access_log.date
FROM Websites
FULL OUTER JOIN access_log
ON Websites.id=access_log.site_id
ORDER BY access_log.count DESC;
# 注释:FULL OUTER JOIN 关键字返回左表(Websites)和右表(access_log)中所有的行。如果 "Websites" 表中的行在 "access_log" 中没有匹配或者 "access_log" 表中的行在 "Websites" 表中没有匹配,也会列出这些行。
SQL 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 语句中的列名。
# 实例
# 下面的 SQL 语句从 "Websites" 和 "apps" 表中选取所有不同的country(只有不同的值):
SELECT country FROM Websites
UNION
SELECT country FROM apps
ORDER BY country;
# 注释:UNION 不能用于列出两个表中所有的country。如果一些网站和APP来自同一个国家,每个国家只会列出一次。UNION 只会选取不同的值。请使用 UNION ALL 来选取重复的值!
# 下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的country(也有重复的值):
SELECT country FROM Websites
UNION ALL
SELECT country FROM apps
ORDER BY country;
# 带有 WHERE 的 SQL UNION ALL
# 下面的 SQL 语句使用 UNION ALL 从 "Websites" 和 "apps" 表中选取所有的中国(CN)的数据(也有重复的值):
SELECT country, name FROM Websites
WHERE country='CN'
UNION ALL
SELECT country, app_name FROM apps
WHERE country='CN'
ORDER BY country;
SQL select into [重点:MySQL 不支持]
select into 语句从一个表复制数据,然后把数据插入到另一个新表中。
注意:MySQL 数据库不支持 select……into 语句,但支持 insert into … select 。
# SQL SELECT INTO 语法
# 我们可以复制所有的列插入到新表中:
SELECT *
INTO newtable [IN externaldb]
FROM table1;
# 或者只复制希望的列插入到新表中:
SELECT column_name(s)
INTO newtable [IN externaldb]
FROM table1;
SQL insert into select
insert into select 语句从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响。
# SQL INSERT INTO SELECT 语法
# 我们可以从一个表中复制所有的列插入到另一个已存在的表中:
INSERT INTO table2
SELECT * FROM table1;
# 或者我们可以只复制希望的列插入到另一个已存在的表中:
INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;
# 实例
# 复制 "apps" 中的数据插入到 "Websites" 中:
INSERT INTO Websites (name, country)
SELECT app_name, country FROM apps;
# 只复 id=1 的数据到 "Websites" 中:
INSERT INTO Websites (name, country)
SELECT app_name, country FROM apps
WHERE id=1;
SQL create database
create database 语句用于创建数据库。
# SQL CREATE DATABASE 语法
CREATE DATABASE dbname;
# SQL CREATE DATABASE 实例
# 下面的 SQL 语句创建一个名为 "my_db" 的数据库:
CREATE DATABASE my_db;
# 数据库表可以通过 CREATE TABLE 语句来添加。
SQL create table 约束 / not null / unique / primary key / foreign key / check / default
create table 语句用于创建数据库中的表。表由行和列组成,每个表都必须有个表名。
- SQL CREATE TABLE 语法
CREATE TABLE table_name
(
column_name1 data_type(size),
column_name2 data_type(size),
column_name3 data_type(size),
…
);
column_name 参数规定表中列的名称。
data_type 参数规定列的数据类型(例如 varchar、integer、decimal、date 等等)。
size 参数规定表中列的最大长度。
提示:如需了解 MS Access、MySQL 和 SQL Server 中可用的数据类型,请访问我们完整的 数据类型参考手册。
# SQL CREATE TABLE 实例
# 现在我们想要创建一个名为 "Persons" 的表,包含五列:PersonID、LastName、FirstName、Address 和 City。
CREATE TABLE Persons
(
PersonID int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);
# PersonID 列的数据类型是 int,包含整数。
# LastName、FirstName、Address 和 City 列的数据类型是 varchar,包含字符,且这些字段的最大长度为 255 个字符。
- SQL 约束(Constraints)
SQL 约束用于规定表中的数据规则。
如果存在违反约束的数据行为,行为会被约束终止。
约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。
- SQL CREATE TABLE + CONSTRAINT 语法
CREATE TABLE table_name
(
column_name1 data_type(size) constraint_name,
column_name2 data_type(size) constraint_name,
column_name3 data_type(size) constraint_name,
…
);
-
在 SQL 中,我们有如下约束:
NOT NULL - 指示某列不能存储 NULL 值。
UNIQUE - 保证某列的每行必须有唯一的值。
PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK - 保证列中的值符合指定的条件。
DEFAULT - 规定没有给列赋值时的默认值。 -
SQL not null 约束
在默认的情况下,表的列接受 null 值。not null 约束强制列不接受 null值。not null 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。
# 下面的 SQL 强制 "ID" 列、 "LastName" 列以及 "FirstName" 列不接受 NULL 值:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255) NOT NULL,
Age int
);
# 加 NOT NULL 约束
# 在一个已创建的表的 "Age" 字段中添加 NOT NULL 约束如下所示:
ALTER TABLE Persons
MODIFY Age int NOT NULL;
# 删除 NOT NULL 约束
# 在一个已创建的表的 "Age" 字段中删除 NOT NULL 约束如下所示:
ALTER TABLE Persons
- SQL unique 约束
unique 约束唯一标识数据库表中的每条记录。unique 和 primary key 约束均为列或列集合提供了唯一性的保证。primary key 约束拥有自动定义的 unique 约束。请注意,每个表可以有多个 unique 约束,但是每个表只能有一个 primary key 约束。
# CREATE TABLE 时的 SQL UNIQUE 约束
# 下面的 SQL 在 "Persons" 表创建时在 "P_Id" 列上创建 UNIQUE 约束:
# MySQL:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
UNIQUE (P_Id)
)
# SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL UNIQUE,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
# 如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束,请使用下面的 SQL 语法:
# MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)
)
# ALTER TABLE 时的 SQL UNIQUE 约束
# 当表已被创建时,如需在 "P_Id" 列创建 UNIQUE 约束,请使用下面的 SQL:
# MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD UNIQUE (P_Id)
#如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束,请使用下面的 SQL 语法:
# MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)
# 撤销 UNIQUE 约束
# 如需撤销 UNIQUE 约束,请使用下面的 SQL:
# MySQL:
ALTER TABLE Persons
DROP INDEX uc_PersonID
# SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT uc_PersonID
- SQL primary key 约束
primary key 约束唯一标识数据库表中的每条记录。
主键必须包含唯一的值。
主键列不能包含 null 值。
每个表都应该有一个主键,并且每个表只能有一个主键。
# CREATE TABLE 时的 SQL PRIMARY KEY 约束
# 下面的 SQL 在 "Persons" 表创建时在 "P_Id" 列上创建 PRIMARY KEY 约束:
# MySQL:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (P_Id)
)
# SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
# 如需命名 PRIMARY KEY 约束,并定义多个列的 PRIMARY KEY 约束,请使用下面的 SQL 语法:
# MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)
# 注释:在上面的实例中,只有一个主键 PRIMARY KEY(pk_PersonID)。然而,pk_PersonID 的值是由两个列(P_Id 和 LastName)组成的。
# ALTER TABLE 时的 SQL PRIMARY KEY 约束
# 当表已被创建时,如需在 "P_Id" 列创建 PRIMARY KEY 约束,请使用下面的 SQL:
# MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD PRIMARY KEY (P_Id)
## 如需命名 PRIMARY KEY 约束,并定义多个列的 PRIMARY KEY 约束,请使用下面的 SQL 语法:
# MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
# 注释:如果您使用 ALTER TABLE 语句添加主键,必须把主键列声明为不包含 NULL 值(在表首次创建时)。
# 撤销 PRIMARY KEY 约束
# 如需撤销 PRIMARY KEY 约束,请使用下面的 SQL:
# MySQL:
ALTER TABLE Persons
DROP PRIMARY KEY
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT pk_PersonID
- SQL foreign key 约束
一个表中的 foreign key 指向另一个表中的 unique key(唯一约束的键)。
# CREATE TABLE 时的 SQL FOREIGN KEY 约束
# 下面的 SQL 在 "Orders" 表创建时在 "P_Id" 列上创建 FOREIGN KEY 约束:
# MySQL:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
)
# SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL PRIMARY KEY,
OrderNo int NOT NULL,
P_Id int FOREIGN KEY REFERENCES Persons(P_Id)
)
# 如需命名 FOREIGN KEY 约束,并定义多个列的 FOREIGN KEY 约束,请使用下面的 SQL 语法:
# MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
)
# ALTER TABLE 时的 SQL FOREIGN KEY 约束
# 当 "Orders" 表已被创建时,如需在 "P_Id" 列创建 FOREIGN KEY 约束,请使用下面的 SQL:
# MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
# 如需命名 FOREIGN KEY 约束,并定义多个列的 FOREIGN KEY 约束,请使用下面的 SQL 语法:
# MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD CONSTRAINT fk_PerOrders
FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
# 撤销 FOREIGN KEY 约束
# 如需撤销 FOREIGN KEY 约束,请使用下面的 SQL:
# MySQL
ALTER TABLE Orders
DROP FOREIGN KEY fk_PerOrders
# SQL Server / Oracle / MS Access:
ALTER TABLE Orders
DROP CONSTRAINT fk_PerOrders
- SQL check 约束
check 约束用于限制列中的值的范围。
如果对单个列定义 check 约束,那么该列只允许特定的值。
如果对一个表定义 check 约束,那么此约束会基于行中其他列的值在特定的列中对值进行限制。
# CREATE TABLE 时的 SQL CHECK 约束
# 下面的 SQL 在 "Persons" 表创建时在 "P_Id" 列上创建 CHECK 约束。CHECK 约束规定 "P_Id" 列必须只包含大于 0 的整数。
# MySQL:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CHECK (P_Id>0)
)
# SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL CHECK (P_Id>0),
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
# 如需命名 CHECK 约束,并定义多个列的 CHECK 约束,请使用下面的 SQL 语法:
# MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')
)
# ALTER TABLE 时的 SQL CHECK 约束
# 当表已被创建时,如需在 "P_Id" 列创建 CHECK 约束,请使用下面的 SQL:
# MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CHECK (P_Id>0)
# 如需命名 CHECK 约束,并定义多个列的 CHECK 约束,请使用下面的 SQL 语法:
# MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')
# 撤销 CHECK 约束
# 如需撤销 CHECK 约束,请使用下面的 SQL:
# SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT chk_Person
# MySQL:
ALTER TABLE Persons
DROP CHECK chk_Person
- SQL default 约束
default 约束用于向列中插入默认值。
如果没有规定其他的值,那么会将默认值添加到所有的新记录。
# CREATE TABLE 时的 SQL DEFAULT 约束
# 下面的 SQL 在 "Persons" 表创建时在 "City" 列上创建 DEFAULT 约束:
# My SQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255) DEFAULT 'Sandnes'
)
# 通过使用类似 GETDATE() 这样的函数,DEFAULT 约束也可以用于插入系统值:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
OrderDate date DEFAULT GETDATE()
)
# ALTER TABLE 时的 SQL DEFAULT 约束
# 当表已被创建时,如需在 "City" 列创建 DEFAULT 约束,请使用下面的 SQL:
# MySQL:
ALTER TABLE Persons
ALTER City SET DEFAULT 'SANDNES'
# SQL Server / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT ab_c DEFAULT 'SANDNES' for City
# Oracle:
ALTER TABLE Persons
MODIFY City DEFAULT 'SANDNES'
# 撤销 DEFAULT 约束
# 如需撤销 DEFAULT 约束,请使用下面的 SQL:
# MySQL:
ALTER TABLE Persons
ALTER City DROP DEFAULT
# SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ALTER COLUMN City DROP DEFAULT
SQL create index
create index 语句用于在表中创建索引。
在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。
- 索引
可以在表中创建索引,以便更加快速高效地查询数据。
用户无法看到索引,它们只能被用来加速搜索/查询。
注释:更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。
# SQL CREATE INDEX 语法
# 在表上创建一个简单的索引。允许使用重复的值:
CREATE INDEX index_name
ON table_name (column_name)
SQL CREATE UNIQUE INDEX 语法
# 在表上创建一个唯一的索引。不允许使用重复的值:唯一的索引意味着两个行不能拥有相同的索引值。Creates a unique index on a table. Duplicate values are not allowed:
CREATE UNIQUE INDEX index_name
ON table_name (column_name)
# 注释:用于创建索引的语法在不同的数据库中不一样。因此,检查您的数据库中创建索引的语法。
# CREATE INDEX 实例
# 下面的 SQL 语句在 "Persons" 表的 "LastName" 列上创建一个名为 "PIndex" 的索引:
CREATE INDEX PIndex
ON Persons (LastName)
# 如果您希望索引不止一个列,您可以在括号中列出这些列的名称,用逗号隔开:
CREATE INDEX PIndex
ON Persons (LastName, FirstName)
SQL drop
通过使用 drop 语句,可以轻松地删除索引、表和数据库。
# DROP INDEX 语句
# DROP INDEX 语句用于删除表中的索引。
# 用于 MS Access 的 DROP INDEX 语法:
DROP INDEX index_name ON table_name
# 用于 MS SQL Server 的 DROP INDEX 语法:
DROP INDEX table_name.index_name
# 用于 DB2/Oracle 的 DROP INDEX 语法:
DROP INDEX index_name
# 用于 MySQL 的 DROP INDEX 语法:
ALTER TABLE table_name DROP INDEX index_name
# DROP TABLE 语句
# DROP TABLE 语句用于删除表。
DROP TABLE table_name
# DROP DATABASE 语句
# DROP DATABASE 语句用于删除数据库。
DROP DATABASE database_name
# TRUNCATE TABLE 语句
# 如果我们仅仅需要删除表内的数据,但并不删除表本身,那么我们该如何做呢?
# 请使用 TRUNCATE TABLE 语句:
TRUNCATE TABLE table_name
SQL alter
alter table 语句用于在已有的表中添加、删除或修改列。
# SQL ALTER TABLE 语法
# 如需在表中添加列,请使用下面的语法:
ALTER TABLE table_name
ADD column_name datatype
# 如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
ALTER TABLE table_name
DROP COLUMN column_name
# 要改变表中列的数据类型,请使用下面的语法:
# SQL Server / MS Access:
ALTER TABLE table_name
ALTER COLUMN column_name datatype
# My SQL / Oracle:
ALTER TABLE table_name
MODIFY COLUMN column_name datatype
# Oracle 10G 之后版本:
ALTER TABLE table_name
MODIFY column_name datatype;
- 在 “Persons” 表中添加一个名为 “DateOfBirth” 的列。
ALTER TABLE Persons
ADD DateOfBirth date
请注意,新列 “DateOfBirth” 的类型是 date,可以存放日期。数据类型规定列中可以存放的数据的类型。如需了解 MS Access、MySQL 和 SQL Server 中可用的数据类型,请参考 完整的 数据类型参考手册。
- 改变 “Persons” 表中 “DateOfBirth” 列的数据类型。
ALTER TABLE Persons
ALTER COLUMN DateOfBirth year
请注意,现在 “DateOfBirth” 列的类型是 year,可以存放 2 位或 4 位格式的年份。
- 删除 “Person” 表中的 “DateOfBirth” 列。
ALTER TABLE Persons
DROP COLUMN DateOfBirth
SQL auto increment
Auto-increment 会在新记录插入表中时生成一个唯一的数字。
# 用于 MySQL 的语法
# 下面的 SQL 语句把 "Persons" 表中的 "ID" 列定义为 auto-increment 主键字段:
CREATE TABLE Persons
(
ID int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (ID)
)
# MySQL 使用 AUTO_INCREMENT 关键字来执行 auto-increment 任务。
# 默认地,AUTO_INCREMENT 的开始值是 1,每条新记录递增 1。
# 要让 AUTO_INCREMENT 序列以其他的值起始,请使用下面的 SQL 语法:
ALTER TABLE Persons AUTO_INCREMENT=100
# 要在 "Persons" 表中插入新记录,我们不必为 "ID" 列规定值(会自动添加一个唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen')
# 上面的 SQL 语句会在 "Persons" 表中插入一条新记录。"ID" 列会被赋予一个唯一的值。"FirstName" 列会被设置为 "Lars","LastName" 列会被设置为 "Monsen"。
# 用于 SQL Server 的语法
# 下面的 SQL 语句把 "Persons" 表中的 "ID" 列定义为 auto-increment 主键字段:
CREATE TABLE Persons
(
ID int IDENTITY(1,1) PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
# MS SQL Server 使用 IDENTITY 关键字来执行 auto-increment 任务。
# 在上面的实例中,IDENTITY 的开始值是 1,每条新记录递增 1。
# 提示:要规定 "ID" 列以 10 起始且递增 5,请把 identity 改为 IDENTITY(10,5)。
# 要在 "Persons" 表中插入新记录,我们不必为 "ID" 列规定值(会自动添加一个唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen')
# 上面的 SQL 语句会在 "Persons" 表中插入一条新记录。"ID" 列会被赋予一个唯一的值。"FirstName" 列会被设置为 "Lars","LastName" 列会被设置为 "Monsen"。
# 用于 Access 的语法
# 下面的 SQL 语句把 "Persons" 表中的 "ID" 列定义为 auto-increment 主键字段:
CREATE TABLE Persons
(
ID Integer PRIMARY KEY AUTOINCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
# MS Access 使用 AUTOINCREMENT 关键字来执行 auto-increment 任务。
# 默认地,AUTOINCREMENT 的开始值是 1,每条新记录递增 1。
# 提示:要规定 "ID" 列以 10 起始且递增 5,请把 autoincrement 改为 AUTOINCREMENT(10,5)。
# 要在 "Persons" 表中插入新记录,我们不必为 "ID" 列规定值(会自动添加一个唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen')
# 上面的 SQL 语句会在 "Persons" 表中插入一条新记录。"ID" 列会被赋予一个唯一的值。"FirstName" 列会被设置为 "Lars","LastName" 列会被设置为 "Monsen"。
# 用于 Oracle 的语法
# 在 Oracle 中,代码稍微复杂一点。
# 您必须通过 sequence 对象(该对象生成数字序列)创建 auto-increment 字段。
# 请使用下面的 CREATE SEQUENCE 语法:
CREATE SEQUENCE seq_person
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10
# 上面的代码创建一个名为 seq_person 的 sequence 对象,它以 1 起始且以 1 递增。该对象缓存 10 个值以提高性能。cache 选项规定了为了提高访问速度要存储多少个序列值。
# 要在 "Persons" 表中插入新记录,我们必须使用 nextval 函数(该函数从 seq_person 序列中取回下一个值):
INSERT INTO Persons (ID,FirstName,LastName)
VALUES (seq_person.nextval,'Lars','Monsen')
# 上面的 SQL 语句会在 "Persons" 表中插入一条新记录。"ID" 列会被赋值为来自 seq_person 序列的下一个数字。"FirstName"列 会被设置为 "Lars","LastName" 列会被设置为 "Monsen"。
SQL 视图
-
SQL create view 语句
在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。
视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。
可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,也可以呈现数据,就像这些数据来自于某个单一的表一样。 -
SQL create view 语法
CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
注释:视图总是显示最新的数据!每当用户查询视图时,数据库引擎通过使用视图的 SQL 语句重建数据。
# SQL CREATE VIEW 实例
# 样本数据库 Northwind 拥有一些被默认安装的视图。
# 视图 "Current Product List" 会从 "Products" 表列出所有正在使用的产品(未停产的产品)。这个视图使用下面的 SQL 创建
CREATE VIEW [Current Product List] AS
SELECT ProductID,ProductName
FROM Products
WHERE Discontinued=No
# 可以像这样查询上面这个视图:
SELECT * FROM [Current Product List]
# Northwind 样本数据库的另一个视图会选取 "Products" 表中所有单位价格高于平均单位价格的产品:
CREATE VIEW [Products Above Average Price] AS
SELECT ProductName,UnitPrice
FROM Products
WHERE UnitPrice>(SELECT AVG(UnitPrice) FROM Products)
# 可以像这样查询上面这个视图:
SELECT * FROM [Products Above Average Price]
# Northwind 样本数据库的另一个视图会计算在 1997 年每个种类的销售总数。请注意,这个视图会从另一个名为 "Product Sales for 1997" 的视图那里选取数据:
CREATE VIEW [Category Sales For 1997] AS
SELECT DISTINCT CategoryName,Sum(ProductSales) AS CategorySales
FROM [Product Sales for 1997]
GROUP BY CategoryName
# 可以像这样查询上面这个视图:
SELECT * FROM [Category Sales For 1997]
# 也可以向查询添加条件。现在,我们仅仅需要查看 "Beverages" 类的销售总数:
SELECT * FROM [Category Sales For 1997]
WHERE CategoryName='Beverages'
# SQL 更新视图
# 可以使用下面的语法来更新视图:
# SQL CREATE OR REPLACE VIEW 语法
CREATE OR REPLACE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
# 现在希望向 "Current Product List" 视图添加 "Category" 列。将通过下列 SQL 更新视图:
CREATE VIEW [Current Product List] AS
SELECT ProductID,ProductName,Category
FROM Products
WHERE Discontinued=No
# SQL Server
ALTER VIEW [ schema_name . ] view_name [ ( column [ ,...n ] ) ]
[ WITH <view_attribute> [ ,...n ] ]
AS select_statement
[ WITH CHECK OPTION ] [ ; ]
<view_attribute> ::=
{
[ ENCRYPTION ]
[ SCHEMABINDING ]
[ VIEW_METADATA ]
}
# schema_name: 视图所属架构的名称。
# view_name: 要更改的视图。
# column: 将成为指定视图的一部分的一个或多个列的名称(以逗号分隔)。
# SQL 撤销视图
# 可以通过 DROP VIEW 命令来删除视图。
# SQL DROP VIEW 语法
DROP VIEW view_name
SQL 日期
处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配。
只要数据包含的只是日期部分,运行查询就不会出问题。但是,如果涉及时间部分,情况就有点复杂了。
在讨论日期查询的复杂性之前,先来看看最重要的内建日期处理函数。
- MySQL Date 函数
下面的表格列出了 MySQL 中最重要的内建日期函数:
函数 | 描述 |
---|---|
NOW() | 返回当前的日期和时间 |
CURDATE() | 返回当前的日期 |
CURTIME() | 返回当前的时间 |
DATE() | 提取日期或日期/时间表达式的日期部分 |
EXTRACT() | 返回日期/时间的单独部分 |
DATE_ADD() | 向日期添加指定的时间间隔 |
DATE_SUB() | 从日期减去指定的时间间隔 |
DATEDIFF() | 返回两个日期之间的天数 |
DATE_FORMAT() | 用不同的格式显示日期/时间 |
- SQL Server Date 函数
下面的表格列出了 SQL Server 中最重要的内建日期函数:
函数 | 描述 |
---|---|
GETDATE() | 返回当前的日期和时间 |
DATEPART() | 返回日期/时间的单独部分 |
DATEADD() | 在日期中添加或减去指定的时间间隔 |
DATEDIFF() | 返回两个日期之间的时间 |
CONVERT() | 用不同的格式显示日期/时间 |
- 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 - 格式:唯一的数字
- MySQL 使用下列数据类型在数据库中存储日期或日期/时间值:
注释:当您在数据库中创建一个新表时,需要为列选择数据类型!
处理日期时,最难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 - 格式:唯一的数字
注释:当您在数据库中创建一个新表时,需要为列选择数据类型!的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配。
只要您的数据包含的只是日期部分,运行查询就不会出问题。但是,如果涉及时间部分,情况就有点复杂了。
在讨论日期查询的复杂性之前,我们先来看看最重要的内建日期处理函数。
SQL null 值
null 值代表遗漏的未知数据。默认地,表的列可以存放 NULL 值。
- SQL null 值
如果表中的某个列是可选的,那么可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 null 值保存。
null 值的处理方式与其他值不同。
null 用作未知的或不适用的值的占位符。
注释:无法比较 null 和 0;它们是不等价的。
# SQL IS NULL
# 如何仅仅选取在 "Address" 列中带有 NULL 值的记录呢?
# 必须使用 IS NULL 操作符:
SELECT LastName,FirstName,Address FROM Persons
WHERE Address IS NULL
# Note:请始终使用 is null 来查找 null 值。
# SQL is not null
# 如何仅仅选取在 "Address" 列中不带有 NULL 值的记录呢?
# 必须使用 is not null 操作符:
SELECT LastName,FirstName,Address FROM Persons
WHERE Address IS NOT NULL
SQL null 函数
SQL isnull()、nvl()、ifnull() 和 coalesce() 函数
# 使用下面的 SELECT 语句:
SELECT ProductName,UnitPrice*(UnitsInStock+UnitsOnOrder)
FROM Products
# 在上面的实例中,如果有 "UnitsOnOrder" 值是 NULL,那么结果是 NULL。
# 微软的 ISNULL() 函数用于规定如何处理 NULL 值。
# NVL()、IFNULL() 和 COALESCE() 函数也可以达到相同的结果。
# 在这里,希望 NULL 值为 0。
# 下面,如果 "UnitsOnOrder" 是 NULL,则不会影响计算,因为如果值是 NULL 则 ISNULL() 返回 0:
# SQL Server / MS Access
SELECT ProductName,UnitPrice*(UnitsInStock+ISNULL(UnitsOnOrder,0))
FROM Products
# Oracle
# Oracle 没有 ISNULL() 函数。不过,可以使用 NVL() 函数达到相同的结果:
SELECT ProductName,UnitPrice*(UnitsInStock+NVL(UnitsOnOrder,0))
FROM Products
# MySQL
# MySQL 也拥有类似 ISNULL() 的函数。不过它的工作方式与微软的 ISNULL() 函数有点不同。
# 在 MySQL 中,我们可以使用 IFNULL() 函数,如下所示:
SELECT ProductName,UnitPrice*(UnitsInStock+IFNULL(UnitsOnOrder,0))
FROM Products
# 或者可以使用 COALESCE() 函数,如下所示:
SELECT ProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0))
FROM Products
SQL 通用数据类型
数据库表中的每个列都要求有名称和数据类型。Each column in a database table is required to have a name and a data type.
SQL 开发人员必须在创建 SQL 表时决定表中的每个列将要存储的数据的类型。数据类型是一个标签,是便于 SQL 了解每个列期望存储什么类型的数据的指南,它也标识了 SQL 如何与存储的数据进行交互。
下面的表格列出了 SQL 中通用的数据类型:
数据类型 | 描述 |
---|---|
CHARACTER(n) | 字符/字符串。固定长度 n。 |
VARCHAR(n) 或 CHARACTER VARYING(n) | 字符/字符串。可变长度。最大长度 n。 |
BINARY(n) | 二进制串。固定长度 n。 |
BOOLEAN | 存储 TRUE 或 FALSE 值 |
VARBINARY(n) 或 BINARY VARYING(n) | 二进制串。可变长度。最大长度 n。 |
INTEGER( p ) | 整数值(没有小数点)。精度 p。 |
SMALLINT | 整数值(没有小数点)。精度 5。 |
INTEGER | 整数值(没有小数点)。精度 10。 |
BIGINT | 整数值(没有小数点)。精度 19。 |
DECIMAL(p,s) | 精确数值,精度 p,小数点后位数 s。例如:decimal(5,2) 是一个小数点前有 3 位数,小数点后有 2 位数的数字。 |
NUMERIC(p,s) | 精确数值,精度 p,小数点后位数 s。(与 DECIMAL 相同) |
FLOAT( p) | 近似数值,尾数精度 p。一个采用以 10 为基数的指数计数法的浮点数。该类型的 size 参数由一个指定最小精度的单一数字组成。 |
REAL | 近似数值,尾数精度 7。 |
FLOAT | 近似数值,尾数精度 16。 |
DOUBLE PRECISION | 近似数值,尾数精度 16。 |
DATE | 存储年、月、日的值。 |
TIME | 存储小时、分、秒的值。 |
TIMESTAMP | 存储年、月、日、小时、分、秒的值。 |
INTERVAL | 由一些整数字段组成,代表一段时间,取决于区间的类型。 |
ARRAY | 元素的固定长度的有序集合 |
MULTISET | 元素的可变长度的无序集合 |
XML | 存储 XML 数据 |
- SQL 数据类型快速参考手册
然而,不同的数据库对数据类型定义提供不同的选择。
下面的表格显示了各种不同的数据库平台上一些数据类型的通用名称:
数据类型 | Access | SQLServer | Oracle | MySQL | PostgreSQL |
---|---|---|---|---|---|
boolean | Yes/No | Bit | Byte | N/A | Boolean |
integer | Number (integer) | Int | Number | Int Integer | Int Integer |
float | Number (single) | Float Real | Number | Float | Numeric |
currency | Currency | Money | N/A | N/A | Money |
string (fixed) | N/A | Char | Char | Char | Char |
string (variable) | Text (<256) Memo (65k+) | Varchar | Varchar Varchar2 | Varchar | Varchar |
binary object | OLE Object Memo | Binary (fixed up to 8K) Varbinary (<8K) Image (<2GB) | Long Raw | Blob Text | Binary Varbinary |
SQL DB 数据类型
Microsoft Access、MySQL 和 SQL Server 所使用的数据类型和范围。
- Microsoft Access 数据类型
数据类型 | 描述 | 存储 |
---|---|---|
Text | 用于文本或文本与数字的组合。最多 255 个字符。 | |
Memo Memo | 用于更大数量的文本。最多存储 65,536 个字符。注释:无法对 memo 字段进行排序。不过它们是可搜索的。 | |
Byte | 允许 0 到 255 的数字。 | 1 字节 |
Integer | 允许介于 -32,768 与 32,767 之间的全部数字。 | 2 字节 |
Long | 允许介于 -2,147,483,648 与 2,147,483,647 之间的全部数字。 | 4 字节 |
Single | 单精度浮点。处理大多数小数。 | 4 字节 |
Double | 双精度浮点。处理大多数小数。 | 8 字节 |
Currency | 用于货币。支持 15 位的元,外加 4 位小数。提示:您可以选择使用哪个国家的货币。 | 8 字节 |
AutoNumber | AutoNumber 字段自动为每条记录分配数字,通常从 1 开始。 | 4 字节 |
Date/Time 用于日期和时间 | 8 字节 | |
Yes/No | 逻辑字段,可以显示为 Yes/No、True/False 或 On/Off。在代码中,使用常量 True 和 False (等价于 1 和 0)。注释:Yes/No 字段中不允许 Null 值 | 1 比特 |
Ole Object | 可以存储图片、音频、视频或其他 BLOBs(Binary Large OBjects)。 | 最多 1GB |
Hyperlink | 包含指向其他文件的链接,包括网页。 | |
Lookup Wizard | 允许您创建一个可从下拉列表中进行选择的选项列表。 | 4 字节 |
- MySQL 数据类型
在 MySQL 中,有三种主要的类型:Text(文本)、Number(数字)和 Date/Time(日期/时间)类型。- Text 类型:
数据类型 | 描述 |
---|---|
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 可存储一个以上的选择。 |
- Number 类型:
数据类型 | 描述 |
---|---|
TINYINT(size) | 带符号-128到127 ,无符号0到255。 |
SMALLINT(size) | 带符号范围-32768到32767,无符号0到65535, size 默认为 6。 |
MEDIUMINT(size) | 带符号范围-8388608到8388607,无符号的范围是0到16777215。 size 默认为9 |
INT(size) | 带符号范围-2147483648到2147483647,无符号的范围是0到4294967295。 size 默认为 11 |
BIGINT(size) | 带符号的范围是-9223372036854775808到9223372036854775807,无符号的范围是0到18446744073709551615。size 默认为 20 |
FLOAT(size,d) | 带有浮动小数点的小数字。在 size 参数中规定显示最大位数。在 d 参数中规定小数点右侧的最大位数。 |
DOUBLE(size,d) | 带有浮动小数点的大数字。在 size 参数中规显示定最大位数。在 d 参数中规定小数点右侧的最大位数。 |
DECIMAL(size,d) | 作为字符串存储的 DOUBLE 类型,允许固定的小数点。在 size 参数中规定显示最大位数。在 d 参数中规定小数点右侧的最大位数。 |
注意:以上的 size 代表的并不是存储在数据库中的具体的长度,如 int(4) 并不是只能存储4个长度的数字。
实际上int(size)所占多少存储空间并无任何关系。int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。就是在显示给用户的方式有点不同外,int(M) 跟 int 数据类型是相同的。
例如:
1、int的值为10 (指定zerofill)
int(9)显示结果为000000010
int(3)显示结果为010
就是显示的长度不一样而已 都是占用四个字节的空间
Date 类型:
数据类型 | 描述 |
---|---|
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。 |
*即便 DATETIME 和 TIMESTAMP 返回相同的格式,它们的工作方式很不同。在 INSERT 或 UPDATE 查询中,TIMESTAMP 自动把自身设置为当前的日期和时间。TIMESTAMP 也接受不同的格式,比如 YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD 或 YYMMDD。
- SQL Server 数据类型
- String 类型:
数据类型 | 描述 | 存储 |
---|---|---|
char(n) 固定长度的字符串。最多 8,000 个字符。 Defined width | ||
varchar(n) 可变长度的字符串。最多 8,000 个字符。 2 bytes + number of chars | ||
varchar(max) 可变长度的字符串。最多 1,073,741,824 个字符。 2 bytes + number of chars | ||
text 可变长度的字符串。最多 2GB 文本数据。 4 bytes + number of chars | ||
nchar 固定长度的 Unicode 字符串。最多 4,000 个字符。 Defined width x 2 | ||
nvarchar 可变长度的 Unicode 字符串。最多 4,000 个字符。 | ||
nvarchar(max) 可变长度的 Unicode 字符串。最多 536,870,912 个字符。 | ||
ntext 可变长度的 Unicode 字符串。最多 2GB 文本数据。 | ||
bit 允许 0、1 或 NULL | ||
binary(n) 固定长度的二进制字符串。最多 8,000 字节。 | ||
varbinary 可变长度的二进制字符串。最多 8,000 字节。 | ||
varbinary(max) 可变长度的二进制字符串。最多 2GB。 | ||
image 可变长度的二进制字符串。最多 2GB。 |
- Number 类型:
数据类型 | 描述 | 存储 |
---|---|---|
tinyint | 允许从 0 到 255 的所有数字。 | 1 字节 |
smallint | 允许介于 -32,768 与 32,767 的所有数字。 | 2 字节 |
int | 允许介于 -2,147,483,648 与 2,147,483,647 的所有数字。 | 4 字节 |
bigint | 允许介于 -9,223,372,036,854,775,808 与 9,223,372,036,854,775,807 之间的所有数字。 | 8 字节 |
decimal(p,s) | 固定精度和比例的数字。 允许从 -10^38 +1 到 10^38 -1 之间的数字。 p 参数指示可以存储的最大位数(小数点左侧和右侧)。p 必须是 1 到 38 之间的值。默认是 18。 s 参数指示小数点右侧存储的最大位数。s 必须是 0 到 p 之间的值。默认是 0。 | 5-17 字节 |
numeric(p,s) | 固定精度和比例的数字。 允许从 -10^38 +1 到 10^38 -1 之间的数字。 p 参数指示可以存储的最大位数(小数点左侧和右侧)。p 必须是 1 到 38 之间的值。默认是 18。 s 参数指示小数点右侧存储的最大位数。s 必须是 0 到 p 之间的值。默认是 0。 | 5-17 字节 |
smallmoney | 介于 -214,748.3648 与 214,748.3647 之间的货币数据。 | 4 字节 |
money | 介于 -922,337,203,685,477.5808 与 922,337,203,685,477.5807 之间的货币数据。 | 8 字节 |
float(n) | 从 -1.79E + 308 到 1.79E + 308 的浮动精度数字数据。 n 参数指示该字段保存 4 字节还是 8 字节。float(24) 保存 4 字节,而 float(53) 保存 8 字节。n 的默认值是 53。 | 4 或 8 字节 |
real | 从 -3.40E + 38 到 3.40E + 38 的浮动精度数字数据。 | 4 字节 |
- Date 类型:
数据类型 | 描述 | 存储 |
---|---|---|
datetime | 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 3.33 毫秒。 | 8 字节 |
datetime2 | 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 100 纳秒。 | 6-8 字节 |
smalldatetime | 从 1900 年 1 月 1 日 到 2079 年 6 月 6 日,精度为 1 分钟。 | 4 字节 |
date | 仅存储日期。从 0001 年 1 月 1 日 到 9999 年 12 月 31 日。 | 3 bytes |
time | 仅存储时间。精度为 100 纳秒。 | 3-5 字节 |
datetimeoffset | 与 datetime2 相同,外加时区偏移。 | 8-10 字节 |
timestamp | 存储唯一的数字,每当创建或修改某行时,该数字会更新。timestamp 值基于内部时钟,不对应真实时间。每个表只能有一个 timestamp 变量。 |
- 其他数据类型:
数据类型 | 描述 |
---|---|
sql_variant | 存储最多 8,000 字节不同数据类型的数据,除了 text、ntext 以及 timestamp。 |
uniqueidentifier | 存储全局唯一标识符 (GUID)。 |
xml | 存储 XML 格式化数据。最多 2GB。 |
cursor | 存储对用于数据库操作的指针的引用。 |
table | 存储结果集,供稍后处理。 |
SQL 函数
SQL 拥有很多可用与计算的内建函数。
函数名称 | 作用 |
---|---|
SQL Aggregate 函数 | 函数计算从列中取得的值,返回一个单一的值 |
avg() | 返回平均值 |
count() | 返回行数 |
first() | 返回第一个记录的值 |
last() | 返回最后一个记录的值 |
max() | 返回最大值 |
min() | 返回最小值 |
sum() | 返回综合 |
SQL Scalar 函数 | 函数基于输入值,返回一个单一的值 |
ucase() | 将某个字段转换为大写 |
lcase() | 将某个字段转换为小写 |
mid() | 从某个文本字段提取字符,MySQL 中使用 |
len() | 返回某个文本字段的长度 |
round() | 对某个数值字段进行指定小数位数的四舍五入 |
now() | 返回当前的系统日期和时间 |
format() | 格式化某个字段的显示方式 |
SQL AVG()
AVG() 函数返回数值列的平均值。
- SQL AVG() 语法
SELECT AVG(column_name) FROM table_name
# 实例
# 从 "access_log" 表的 "count" 列获取平均值:
SELECT AVG(count) AS CountAverage FROM access_log;
# 选择访问量高于平均访问量的 "site_id" 和 "count":
SELECT site_id, count FROM access_log
WHERE count > (SELECT AVG(count) FROM access_log);
SQL count()
count() 函数返回匹配指定条件的行数。
- SQL count(column_name) 语法
count(column_name) 函数返回指定列的值的数目(NULL 不计入):
select count(column_name) from table_name;
- SQL count() 语法
count() 函数返回表中的记录数:
select count(*) from table_name;
- SQL count(distinct column_name) 语法
count(distinct column_name) 函数返回指定列的不同值的数目:
select count(distinct column_name) FROM table_name;
注意:COUNT(DISTINCT) 适用于 oracle 和 Microsoft SQL Server,但是无法用于 Microsoft Access。
# 计算 "access_log" 表中 "site_id"=3 的总访问量:
SELECT COUNT(count) AS nums FROM access_log
WHERE site_id=3;
# 计算 "access_log" 表中总记录数
SELECT COUNT(*) AS nums FROM access_log;
# 计算 "access_log" 表中不同 site_id 的记录数:
SELECT COUNT(DISTINCT site_id) AS nums FROM access_log;
SQL first() & last()
first() 函数返回指定的列中第一个记录的值。
LAST() 函数返回指定的列中最后一个记录的值。
SQL LAST() 语法
- SQL first() & last() 语法
select first(column_name) from table_name;
select last(column_name) from table_name;
注意:只有 MS Access 支持 first() 函数。
# first()
# SQL Server 语法
SELECT TOP 1 column_name FROM table_name
ORDER BY column_name ASC;
# 实例
SELECT TOP 1 name FROM Websites
ORDER BY id ASC;
# MySQL 语法
SELECT column_name FROM table_name
ORDER BY column_name ASC
LIMIT 1;
# 实例
SELECT name FROM Websites
ORDER BY id ASC
LIMIT 1;
# Oracle 语法
SELECT column_name FROM table_name
ORDER BY column_name ASC
WHERE ROWNUM <=1;
# 实例
SELECT name FROM Websites
ORDER BY id ASC
WHERE ROWNUM <=1;
# last()
# SQL Server 语法
SELECT TOP 1 column_name FROM table_name
ORDER BY column_name DESC;
# 实例
SELECT TOP 1 name FROM Websites
ORDER BY id DESC;
# MySQL 语法
SELECT column_name FROM table_name
ORDER BY column_name DESC
LIMIT 1;
# 实例
SELECT name FROM Websites
ORDER BY id DESC
LIMIT 1;
# Oracle 语法
SELECT column_name FROM table_name
ORDER BY column_name DESC
WHERE ROWNUM <=1;
# 实例
SELECT name FROM Websites
ORDER BY id DESC
WHERE ROWNUM <=1;
SQL max() & min()
MAX() 函数返回指定列的最大值。
- SQL max() & min() 语法
select max(column_name) from table_name;
select min(column_name) from table_name;
# max() 实例
SELECT MAX(alexa) AS max_alexa FROM Websites;
# min() 实例
SELECT MIN(alexa) AS min_alexa FROM Websites;
SQL sum()
sum() 函数返回数值列的总数。
- SQL sum() 语法
select sum(column_name) from table_name;
# 实例
SELECT SUM(count) AS nums FROM access_log;
SQL group by
group by
语句用于结合聚合函数,根据一个或多个列对结果集进行分组。
- SQL
group by
语法
select column_name, aggregate_function(column_name)
from table_name
where column_name operator value
group by column_name;
# GROUP BY 简单应用
# 统计 access_log 各个 site_id 的访问量:
SELECT site_id, SUM(access_log.count) AS nums
FROM access_log GROUP BY site_id;
# SQL GROUP BY 多表连接
# SQL 语句统计有记录的网站的记录数量:
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;
SQL 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;
where 和having之后都是筛选条件,但是有区别的:
- where在group by前, having在group by 之后
- 聚合函数(avg、sum、max、min、count),不能作为条件放在where之后,但可以放在having之后
# SQL having 实例
# 现在我们想要查找总访问量大于 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;
# 想要查找总访问量大于 200 的网站,并且 alexa 排名小于 200。
# 在 SQL 语句中增加一个普通的 WHERE 子句:
SELECT Websites.name, SUM(access_log.count) AS nums FROM Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id
WHERE Websites.alexa < 200
GROUP BY Websites.name
HAVING SUM(access_log.count) > 200;
SQL exists (附 演示数据库1 & 2)
exists 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False。
- SQL exists 语法
SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);
演示数据库1:
id | name | url | alexa | country |
---|---|---|---|---|
1 | https://www.google.cm/ | 1 | USA | |
2 | 淘宝 | https://www.taobao.com/ | 13 | CN |
3 | 菜鸟教程 | http://www.runoob.com/ | 4689 | CN |
4 | 微博 | http://weibo.com/ | 20 | CN |
5 | https://www.facebook.com/ | 3 | USA |
演示数据库2:
aid | site_id | count | date |
---|---|---|---|
1 | 1 | 45 | 2016-05-10 |
2 | 3 | 100 | 2016-05-13 |
3 | 1 | 230 | 2016-05-14 |
4 | 2 | 10 | 2016-05-14 |
5 | 5 | 205 | 2016-05-14 |
6 | 4 | 13 | 2016-05-15 |
7 | 3 | 220 | 2016-05-15 |
8 | 5 | 545 | 2016-05-16 |
9 | 3 | 201 | 2016-05-17 |
# 查找总访问量(count 字段)大于 200 的网站是否存在。
# 实例
SELECT Websites.name, Websites.url
FROM Websites
WHERE EXISTS (SELECT count FROM access_log WHERE Websites.id = access_log.site_id AND count > 200);
# exists 可以与 NOT 一同使用,查找出不符合查询语句的记录:
SELECT Websites.name, Websites.url
FROM Websites
WHERE NOT EXISTS (SELECT count FROM access_log WHERE Websites.id = access_log.site_id AND count > 200);
SQL 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;
# SQL UCASE() 实例
# 下面的 SQL 语句从 "Websites" 表中选取 "name" 和 "url" 列,并把 "name" 列的值转换为大写:
SELECT UCASE(name) AS site_title, url
FROM Websites;
# SQL LCASE() 实例
# 下面的 SQL 语句从 "Websites" 表中选取 "name" 和 "url" 列,并把 "name" 列的值转换为小写:
SELECT LCASE(name) AS site_title, url
FROM Websites;
SQL mid()
mid() 函数用于从文本字段中提取字符。
- SQL MID() 语法
select mid(column_name,start[,length]) from table_name;
参数 | 描述 |
---|---|
column_name | 必需。要提取字符的字段。 |
start | 必需。规定开始位置(起始值是 1) |
length | 可选。要返回的字符数。如果省略,则 MID() 函数返回剩余文本 |
# SQL 语句从 "Websites" 表的 "name" 列中提取前 4 个字符:
SELECT MID(name,1,4) AS ShortTitle
FROM Websites;
SQL len()
len() 函数返回文本字段中值的长度。
- SQL len() 语法
select len(column_name) from table_name;
- MySQL 中函数为 length():
select length(column_name) from table_name;
# 语句从 "Websites" 表中选取 "name" 和 "url" 列中值的长度:
SELECT name, LENGTH(url) as LengthOfURL
FROM Websites;
SQL round()
round() 函数用于把数值字段舍入为指定的小数位数。
- SQL round() 语法
select round(column_name,decimals) from table_name;
参数 | 描述 |
---|---|
column_name | 必需。要舍入的字段 |
decimals | 必需。规定要返回的小数位数 |
# ROUND(X): 返回参数X的四舍五入的一个整数。
mysql> select ROUND(-1.23);
-> -1
mysql> select ROUND(-1.58);
-> -2
mysql> select ROUND(1.58);
-> 2
# ROUND(X,D): 返回参数X的四舍五入的有 D 位小数的一个数字。如果D为0,结果将没有小数点或小数部分。
mysql> select ROUND(1.298, 1);
-> 1.3
mysql> select ROUND(1.298, 0);
-> 1
# 注意:ROUND 返回值被变换为一个bigint!
SQL now()
now() 函数返回当前系统的日期和时间。
- SQL now() 语法
select now() from table_name;
# SQL 语句从 "Websites" 表中选取 name,url,及当天日期:
SELECT name, url, Now() AS date
FROM Websites;
# 输出例子 2016-05-18 17:38:29
SQL format()
format() 函数用于对字段的显示进行格式化。
- SQL format() 语法
select format(column_name,format) from table_name;
参数 | 描述 |
---|---|
column_name | 必需。要格式化的字段 |
format | 必需。规定格式 |
# SQL 语句从 "Websites" 表中选取 name, url 以及格式化为 YYYY-MM-DD 的日期:
SELECT name, url, DATE_FORMAT(Now(),'%Y-%m-%d') AS date
FROM Websites;
SQL 快速参考
SQL 语句 | 语法 |
---|---|
and/or | SELECT column_name(s) |
alter table | ALTER TABLE table_name |
as (alias) | SELECT column_name AS column_alias |
between | SELECT column_name(s) |
create database | CREATE DATABASE database_name |
create table | CREATE TABLE table_name |
create index | CREATE INDEX index_name |
create view | CREATE VIEW view_name AS |
delete | DELETE FROM table_name |
drop database | DROP DATABASE database_name |
drop index | DROP INDEX table_name.index_name (SQL Server) |
drop table | DROP TABLE table_name |
group by | SELECT column_name, aggregate_function(column_name) |
having | SELECT column_name, aggregate_function(column_name) |
in | SELECT column_name(s) |
insert into | INSERT INTO table_name |
inner join | SELECT column_name(s) |
left join | SELECT column_name(s) |
right join | SELECT column_name(s) |
full join | SELECT column_name(s) |
like | SELECT column_name(s) |
order by | SELECT column_name(s) |
select | SELECT column_name(s) |
select * | SELECT * |
select distinct | SELECT DISTINCT column_name(s) |
select into | SELECT * INTO new_table_name [IN externaldatabase] |
select top | SELECT TOP number|percent column_name(s) |
truncate table | TRUNCATE TABLE table_name |
union | SELECT column_name(s) FROM table_name1 |
union all | SELECT column_name(s) FROM table_name1 |
update | UPDATE table_name |
where | SELECT column_name(s) |
SQL 主机
想要网站存储数据在数据库并从数据库显示数据, Web 服务器必须能使用 SQL 语言访问数据库系统。
如果 Web 服务器托管在互联网服务提供商(ISP,全称 Internet Service Provider),必须寻找 SQL 主机计划。
最常见的 SQL 主机数据库是 MySQL、MS SQL Server 和 MS Access。
可以在 Windows 和 Linux/UNIX 操作系统上运行 SQL 主机数据库。
下面是操作系统上对应运行的数据库系统的概览。
MS SQL Server
在 Windows 和 Linux 操作系统上运行。
MySQL
在 Windows, Mac OS X 和 Linux/UNIX 操作系统上运行。
MS Access(只建议用于小型网站)
只在 Windows OS 上运行。
总结 (接下来的学习资源 来源于菜鸟)
讲解了用来访问和处理数据库系统的标准计算机语言。
学习了如何使用 SQL 在数据库中执行查询、获取数据、插入新的记录、删除记录以及更新记录。如何通过 SQL 创建数据库、表、索引,以及如何撤销它们。 SQL 中最重要的 Aggregate 函数。
SQL 是一种与数据库系统协同工作的标准语言,这些数据库系统包括 MS SQL Server、IBM DB2、Oracle、MySQL 和 MS Access 等等。