INDEX 语句(索引)
索引
您可以在表中创建索引,以便更加快速高效地查询数据。
用户无法看到索引,它们只能被用来加速搜索/查询。
注释:更新一个包含索引的表需要比更新一个没有索引的表更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。
SQl Server 的索引有三种
唯一索引(UNIQUE),聚集索引(CLUSTERED) ,非聚集索引(NONCLUSTERED)。
--在表中存在主键时无法创建聚集索引,并且一个表只能有一个聚合索引,
添加主键时会默认添加一个索引,对有主键的表执行 sp_helpindex tableName 就可以看见
--唯一索引
sp_helpindex test
create unique index index_name on test (id)
drop index index_name on test
--聚合索引
sp_helpindex test
create clustered index index_name1 on test(inputTime) --在表中存在主键时无法创建聚集索引,并且一个表只能有一个聚合索引
drop index index_name1 on test
--唯一聚合索引
sp_helpindex test
create unique clustered index index_name3 on test(id) --在表中存在主键时无法创建聚集索引,并且一个表只能有一个聚合索引
drop index index_name on test
--非聚合聚合索引
sp_helpindex test2
create nonclustered index index_name1 on test2(id)
drop index index_name1 on test2
TRUNCATE 清除表数据
清除表内的全部数据,比delete 命令快
truncate table test
SQL ALTER TABLE 语句
添加一列
alter table test add remark nvarcahr(50)
删除一列
alter table test drop column remark
修改一行
alter table test alter column remark date
主键自增长
各个数据库之间不同
用于 MySQL 的语法
下列 SQL 语句把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键:
CREATE TABLE Persons (P_Id int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255),PRIMARY KEY (P_Id)
)
用于 SQL Server 的语法
下列 SQL 语句把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键:
CREATE TABLE Persons
(
P_Id int PRIMARY KEY IDENTITY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
默认是 identity(1,1) / identity
已经存在的列不支持修改为自增长,需要删除该列再添加,如果该列有约束还需要先去删除约束,所以在建表时一定要小心,
alter table orders drop column id_p
alter table orders add id_p int primary key identity(1,1)
用于 Access 的语法
下列 SQL 语句把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键:
CREATE TABLE Persons
(
P_Id int PRIMARY KEY AUTOINCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
用于 Oracle 的语法
在Oracle 中没有 类似的东西 做自增长
只能自己 创建一个序列来做 自增长
CREATE SEQUENCE seq_person
MINVALUE 1 --最小值
START WITH 1 -- 由1开始
INCREMENT BY 1 --每次加一
CACHE 10 --缓存10个,以供使用,(即后面10个都已经安排好了,等着用)
使用方法:
INSERT INTO Persons (P_Id,FirstName,LastName)VALUES (seq_person.nextval,'Lars','Monsen')
SQL CREATE VIEW 语句
什么是视图?
在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。
视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。
注释:数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。
--创建视图
create view order_detail as
select p.*,o.orderNo from
orders o left join person p on o.id_p = p.id_p
--修改视图
alter view order_detail as
select p.*,o.orderNo from
orders o left join person p on o.id_p = p.id_p
--删除视图
drop view order_detail
SQL Date 函数
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() | 用不同的格式显示日期/时间 |
返回部分:
select DATEPART(yyyy,getdate())
结果:
时间添加:
select DATEADD(month,2,getdate())
结果:
查询两个时间之间的间隔:
select DATEDIFF(day,getdate(),dateadd(month,2,getdate())) as 相隔天数
结果:
NULL
对null 的查询 需要用
is null 或者 is not null 来定位
查询
NULL 函数
ISNULL()、NVL()、IFNULL() 和 COALESCE() 函数
在上面学习了 如何查询为空的 目标行, 但是在需要运算的过程中 某条数据有null 存在,结果是null这显然不是想要的结果,我们需要在这种时候对 null代表的含义进行指明
请看下面的 "Products" 表:
P_Id | ProductName | UnitPrice | UnitsInStock | UnitsOnOrder |
---|---|---|---|---|
1 | computer | 699 | 25 | 15 |
2 | printer | 365 | 36 | |
3 | telephone | 280 | 159 | 57 |
假如 "UnitsOnOrder" 是可选的,而且可以包含 NULL 值。
执行以下语句 :
select Productname ,unitprice * (unitsinstock + unitsonorder) from products
结果:
在现实情境中我们需要指定 null 为 0
修改语句如下: 当该列的值为null 时就会被认为是 0 来处理
select Productname ,unitprice * (unitsinstock + isnull(unitsonorder,0) ) from products
结果:
以上是SQL SERVER 的方式 :
oracle : NVL()
mysql :IFNULL() 和 COALESCE()
函数的用法都是一样的
SQL Server 数据类型
Character 字符串:
数据类型 | 描述 | 存储 |
---|---|---|
char(n) | 固定长度的字符串。最多 8,000 个字符。 | n |
varchar(n) | 可变长度的字符串。最多 8,000 个字符。 | |
varchar(max) | 可变长度的字符串。最多 1,073,741,824 个字符。 | |
text | 可变长度的字符串。最多 2GB 字符数据。 |
Unicode 字符串:
数据类型 | 描述 | 存储 |
---|---|---|
nchar(n) | 固定长度的 Unicode 数据。最多 4,000 个字符。 | |
nvarchar(n) | 可变长度的 Unicode 数据。最多 4,000 个字符。 | |
nvarchar(max) | 可变长度的 Unicode 数据。最多 536,870,912 个字符。 | |
ntext | 可变长度的 Unicode 数据。最多 2GB 字符数据。 |
Binary 类型:
数据类型 | 描述 | 存储 |
---|---|---|
bit | 允许 0、1 或 NULL | |
binary(n) | 固定长度的二进制数据。最多 8,000 字节。 | |
varbinary(n) | 可变长度的二进制数据。最多 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 bytes |
datetime2 | 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 100 纳秒。 | 6-8 bytes |
smalldatetime | 从 1900 年 1 月 1 日 到 2079 年 6 月 6 日,精度为 1 分钟。 | 4 bytes |
date | 仅存储日期。从 0001 年 1 月 1 日 到 9999 年 12 月 31 日。 | 3 bytes |
time | 仅存储时间。精度为 100 纳秒。 | 3-5 bytes |
datetimeoffset | 与 datetime2 相同,外加时区偏移。 | 8-10 bytes |
timestamp | 存储唯一的数字,每当创建或修改某行时,该数字会更新。timestamp 基于内部时钟,不对应真实时间。每个表只能有一个 timestamp 变量。 |
其他数据类型:
数据类型 | 描述 |
---|---|
sql_variant | 存储最多 8,000 字节不同数据类型的数据,除了 text、ntext 以及 timestamp。 |
uniqueidentifier | 存储全局标识符 (GUID)。 |
xml | 存储 XML 格式化数据。最多 2GB。 |
cursor | 存储对用于数据库操作的指针的引用。 |
table | 存储结果集,供稍后处理。 |
聚合函数
函数 | 描述 |
---|---|
AVG(column) | 返回某列的平均值 |
COUNT(column) | 返回某列的行数(不包括NULL值) |
COUNT(*) | 返回被选行数 |
COUNT(DISTINCT column) | 返回相异结果的数目 |
MAX(column) | 返回某列的最高值 |
MIN(column) | 返回某列的最低值 |
SUM(column) | 返回某列的总和 |
SQL GROUP BY 语句
聚合函数常常配合 GROUP BY 使用
GROUP BY 语句用于结合聚合函数,根据一个或多个列对结果集进行分组。
SELECT Customer,SUM(OrderPrice) FROM Orders GROUP BY Customer
SQL HAVING 子句
也是 与 group by 配套使用的,因为在 group by 后面再写where 条件会报错
SQL HAVING 实例
我们拥有下面这个 "Orders" 表:
O_Id | OrderDate | OrderPrice | Customer |
---|---|---|---|
1 | 2008/12/29 | 1000 | Bush |
2 | 2008/11/23 | 1600 | Carter |
3 | 2008/10/05 | 700 | Bush |
4 | 2008/09/28 | 300 | Bush |
5 | 2008/08/06 | 2000 | Adams |
6 | 2008/07/21 | 100 | Carter |
现在,我们希望查找订单总金额少于 2000 的客户。
我们使用如下 SQL 语句:
SELECT Customer,SUM(OrderPrice) FROM Orders GROUP BY Customer HAVING SUM(OrderPrice)<2000
结果集类似:
Customer | SUM(OrderPrice) |
---|---|
Carter | 1700 |
现在我们希望查找客户 "Bush" 或 "Adams" 拥有超过 1500 的订单总金额。
我们在 SQL 语句中增加了一个普通的 WHERE 子句:
SELECT Customer,SUM(OrderPrice) FROM Orders WHERE Customer='Bush' OR Customer='Adams' GROUP BY Customer HAVING SUM(OrderPrice)>1500
结果集:
Customer | SUM(OrderPrice) |
---|---|
Bush | 2000 |
Adams | 2000 |
大小写转换
select upper(ProductName) from Products
select lower(ProductName) from Products
Left 函数 Right 函数
从左边起保留多少位:
配合 len( ) 函数使用效果更佳
select left(ProductName,len(ProductName)-1) from Products--去掉最后一个字符
select Right (ProductName,len(ProductName)-1) from Products --去掉最前面的一个字符
SQL ROUND() 函数
ROUND() 函数
ROUND 函数用于把数值字段舍入为指定的小数位数。
原来:
select UnitPrice from Products
结果:
保留一位:
select ROUND(UnitPrice,1) from Products
结果:
SQL FORMAT() 函数
select format(getdate(),'yyyy-mm-dd')
结果: