SQL常用操作(下)

约束 (Constraints)

用于规定表中的数据规则。如果存在违反约束的数据行为,行为会被约束终止。

约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。

CREATE TABLE + CONSTRAINT语法:

CREATE TABLE table_name

(

column_name1 data_type(sizeconstraint_name,

column_name2 data_type(sizeconstraint_name,

column_name3 data_type(sizeconstraint_name,

....

);

主要有约束:NOT NULL,UNIQUE,PRIMARY KEY,FOREIGN KEY,CHECK,DEFAULT

1.NOT NULL :强制列不接受NULL(空)值

约束Id_p和Lastname不能为空

2.UNIQUE:约束唯一标识数据库表中的每条记录。

UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。

PRIMARY KEY 拥有自动定义的 UNIQUE 约束。

请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。

(1)在 "Persons" 表创建时在 "Id_P" 列创建 UNIQUE 约束

SQL Server / Oracle / MS Access:

注意:不同数据库,UNIQUE约束所在位置不同。

如果需要命名 UNIQUE 约束,以及为多个列定义 UNIQUE 约束,使用下面的SQL语法:

(2)当表已被创建时,如需在 "Id_P" 列创建 UNIQUE 约束

当表已被创建时,如需在 "Id_P" 列创建 UNIQUE 约束,通过使用ALTER TABLE语句修改,如下:

ALTER TABLE Persons ADD UNIQUE (Id_P)

如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束:

ALTER TABLE PersonsADD CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)

(3)撤销 UNIQUE 约束

MySQL:    ALTER TABLE Persons DROP INDEX uc_PersonID;

SQL Server / Oracle / MS Access:    ALTER TABLE Persons DROP CONSTRAINT uc_PersonID;


3.PRIMARY KEY : 约束唯一标识数据库表中的每条记录。

主键必须包含唯一的值;主键列不能包含 NULL 值;每个表都应该有一个主键,并且每个表只能有一个主键。

(1)在 "Persons" 表创建时在 "Id_P" 列创建 PRIMARY KEY 约束:

如果需要命名 PRIMARY KEY 约束,以及为多个列定义 PRIMARY KEY 约束:

(2)在表已存在的情况下为 "Id_P" 列创建 PRIMARY KEY 约束:

ALTER TABLE Persons ADD PRIMARY KEY (Id_P);

如果需要命名 PRIMARY KEY 约束,以及为多个列定义 PRIMARY KEY 约束:

ALTER TABLE Persons ADD CONSTRAINT pk_PersonID PRIMARY KEY (Id_P,LastName)

(3)撤销 PRIMARY KEY 约束

MySQL:   ALTER TABLE Persons DROP PRIMARY KEY

SQL Server / Oracle / MS Access:   ALTER TABLE Persons DROP CONSTRAINT pk_PersonID


4.FOREIGN KEY:用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。

一个表中的 FOREIGN KEY 指向另一个表中的 PRIMARY KEY。(多对一的关系)

(1)在 "Orders" 表创建时为 "Id_P" 列创建 FOREIGN KEY:

如果需要命名 FOREIGN KEY 约束,以及为多个列定义 FOREIGN KEY 约束:

(2)在 "Orders" 表已存在的情况下为 "Id_P" 列创建 FOREIGN KEY 约束:

如果需要命名 FOREIGN KEY 约束,以及为多个列定义 FOREIGN KEY 约束:

(3)撤销 FOREIGN KEY 约束

5.CHECK:用于限制列中的值的范围

如果对单个列定义 CHECK 约束,那么该列只允许特定的值;如果对一个表定义 CHECK 约束,那么此约束会在特定的列中对值进行限制。

(1)在 "Persons" 表创建时为 "Id_P" 列创建 CHECK 约束。CHECK 约束规定 "Id_P" 列必须只包含大于 0 的整数。

如果需要命名 CHECK 约束,以及为多个列定义 CHECK 约束:

(2)在表已存在的情况下为 "Id_P" 列创建 CHECK 约束:

ALTER TABLE Persons ADD CHECK (Id_P>0);

如果需要命名 CHECK 约束,以及为多个列定义 CHECK 约束:

ALTER TABLE Persons ADD CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes');

(3)撤销 CHECK 约束

MySQL:   ALTER TABLE Persons DROP CHECK chk_Person;

SQL Server / Oracle / MS Access:    ALTER TABLE Persons DROP CONSTRAINT chk_Person;

6.DEFAULT 约束:用于向列中插入默认值。如果没有规定其他的值,那么会将默认值添加到所有的新记录。

(1)在 "Persons" 表创建时为 "City" 列创建 DEFAULT 约束:

城市若没规定,就会默认为Sandnes

通过使用类似 GETDATE() 这样的函数,DEFAULT 约束也可以用于插入系统值:

系统日期

(2)在表已存在的情况下为 "City" 列创建 DEFAULT 约束:

MySQL:   ALTER TABLE Persons ALTER City SET DEFAULT 'SANDNES'

SQL Server / Oracle / MS Access:    ALTER TABLE Persons ALTER COLUMN City SET DEFAULT 'SANDNES'

(3)撤销 DEFAULT 约束

MySQL:   ALTER TABLE Persons ALTER City DROP DEFAULT

SQL Server / Oracle / MS Access:   ALTER TABLE Persons ALTER COLUMN City DROP DEFAULT


CREATE INDEX 语句

用于在表中创建索引。在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。

索引:

您可以在表中创建索引,以便更加快速高效地查询数据。

用户无法看到索引,它们只能被用来加速搜索/查询。

注释:更新一个包含索引的表需要比更新一个没有索引的表更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。

1.CREATE INDEX 语法:

在表上创建一个简单的索引。允许使用重复的值:

CREATE INDEX index_name ON table_name (column_name)

CREATE UNIQUE INDEX 语法:

在表上创建一个唯一的索引。唯一的索引意味着两个行不能拥有相同的索引值。

CREATE UNIQUE INDEX index_name ON table_name (column_name)

注释:"column_name" 规定需要索引的列

CREATE INDEX 实例:

(1)在 Persons 表的 LastName 列,创建名为 "PersonIndex"的索引:

CREATE INDEX PersonIndex ON Persons (LastName)

(2)以降序索引某个列中的值:

CREATE INDEX PersonIndex ON Person (LastName DESC)

(3)索引多列:

CREATE INDEX PersonIndex ON Person (LastName, FirstName)


DROP 撤销索引、表以及数据库

DROP INDEX 语句:删除表格中的索引

语法:

MySQL:   ALTER TABLE table_name DROP INDEX index_name

Microsoft SQLJet / Microsoft Access:    DROP INDEX index_name ON table_name

MS SQL Server :    DROP INDEX table_name.index_name

DROP TABLE 语句:用于删除表(表的结构、属性以及索引也会被删除)

语法:DROP TABLE 表名称

DROP DATABASE 语句:用于删除数据库

语法:DROP DATABASE 语句

TRUNCATE TABLE 语句:仅仅删除表格中的数据,但不删除表的结构

语法:TRUNCATE TABLE 表名称

SQL关于删除的三个语句:DROP、TRUNCATE、 DELETE 的区别:

相同点:drop、delete、truncate 都是删除表的内容。

不同点:

 delete:删除表的内容,表的结构还存在,不释放空间,可以回滚恢复;

 drop:删除表内容和结构,释放空间,没有备份表之前要慎用;

 truncate:删除表的内容,表的结构存在,可以释放空间,没有备份表之前要慎用;

执行速度:drop > truncate > delete


ALTER TABLE 语句

用于在已有的表中添加、修改或删除列

1.添加列

ALTER TABLE table_name ADD column_name datatype

2.删除列

ALTER TABLE table_name DROP COLUMN column_name

注释:某些数据库系统不允许这种在数据库表中删除列的方式 (DROP COLUMN column_name)。

3.改变数据类型

ALTER TABLE table_name ALTER COLUMN column_name datatype


AUTO INCREMENT 字段

会在新纪录插入表时生成一个唯一的数字,可自动地创建主键字段的值

MySQL语法:

把 "Persons" 表中的 "P_Id" 列定义为 auto-increment 主键:

再插入新的记录时不必为 "P_Id" 列规定值,会自动添加唯一的值。

MySQL 使用 AUTO_INCREMENT 关键字来执行 auto-increment 任务,默认地开始值是 1,每条新记录递增 1。

要让 AUTO_INCREMENT 序列以其他的值起始,请使用下列 SQL 语法:

ALTER TABLE Persons AUTO_INCREMENT=100;

SQL Server 的语法:

使用 IDENTITY 关键字

要规定 "P_Id" 列以 20 起始且递增 10,请把 identity 改为 IDENTITY(20,10)。

Access 的语法:

规定 "P_Id" 列以 20 起始且递增10,请把 autoincrement 改为AUTOINCREMENT(20,10)。


VIEW(视图)

视图是基于 SQL 语句的结果集的可视化的表。

视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。

注释:数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。

CREATE VIEW 语法:

CREATE VIEW view_name AS SELECT column_name(s) FROM table_name WHERE condition;

注释:视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。


NULL 值

是遗漏的未知数据,默认地,表的列可以存放 NULL 值。

如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL 值保存。

NULL 值的处理方式与其他值不同。NULL 用作未知的或不适用的值的占位符。

注释:无法比较 NULL 和 0;它们是不等价的。

Persons表:

假如 "Persons" 表中的 "Address" 列是可选的。这意味着如果在 "Address" 列插入一条不带值的记录,"Address" 列会使用 NULL 值保存。

IS NULL

用来测试是否NULL值

要想选取Address列的NULL值记录,就需要使用IS NULL操作符,如:

SELECT LastName,FirstName,Address FROM Persons WHERE Address IS NULL

提示:请始终使用 IS NULL 来查找 NULL 值。因为无法使用比较运算符来测试 NULL 值,比如 =, <, 或者 <>。

 IS NOT NULL

要想选取Address列中不是NULL值的记录,就需要使用IS NOT NULL操作符,如:

SELECT LastName,FirstName,Address FROM Persons WHERE Address IS NOT NULL


数据类型

MySQL 中有三种主要的类型:文本、数字和日期/时间类型。

TEXT文本类型:

Number类型:

注意:这些整数类型拥有额外的选项 UNSIGNED。通常,整数可以是负数或正数。如果添加 UNSIGNED 属性,那么范围将从 0 开始,而不是某个负数。

Date类型:

* 即便 DATETIME 和 TIMESTAMP 返回相同的格式,它们的工作方式很不同。在 INSERT 或 UPDATE 查询中,TIMESTAMP 自动把自身设置为当前的日期和时间。TIMESTAMP 也接受不同的格式,比如 YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD 或 YYMMDD。

Microsoft Access/ SQL Server 数据类型,大家可以网上搜搜,我就不说了。

DATE 函数

当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配。只要数据包含的只是日期部分,运行查询就不会出问题。但是,如果涉及时间,情况就有点复杂了。

在讨论日期查询的复杂性之前,我们先来看看最重要的内建日期处理函数。

MySQL内建重要date函数:

SQL Server:

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 - 格式: 唯一的数字

日期处理

如果不涉及时间部分,那么我们可以轻松地比较两个日期!

假设我们有下面这个 "Orders" 表:

查询OrderDate是“2020-01-06”的记录:

SELECT * FROM Orders where orderdate='2020-01-06';

结果集

现在假设 "Orders" 类似这样(注意 "OrderDate" 列中的时间部分):

在使用上面的查询语句:

SELECT * FROM Orders where orderdate='2020-01-06';

这时我们得不到结果。因为该查询不含有时间部分的日期。

提示:如果您希望使查询简单且更易维护,那么请不要在日期中使用时间部分!

NULL 函数

ISNULL()、NVL()、IFNULL() 和 COALESCE() 函数

"Product"表:

假如 "UnitsOnOrder" 是可选的,而且可以包含 NULL 值。

SELECT ProductName,UnitPrice*(UnitsInStock+UnitsOnOrder) FROM Products;

上面查询语句中,如果有 "UnitsOnOrder" 值是 NULL,那么结果是 NULL,此时不利于计算,为了方便计算,我们将NULL值返回0即可,那么如何做呢?ISNULL(),NVL(), IFNULL() 和 COALESCE()   函数可以处理 NULL 值。如下:

MySQL:

SELECT ProductName,UnitPrice*(UnitsInStock+IFNULL(UnitsOnOrder,0)) FROM Products

或者我们可以使用 COALESCE() 函数,就像这样:

SELECT ProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0)) FROM Products

IFNULL判断是否为空,若为真返回0,否则返回当前值,Coalesce() 同理。

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

以上4个函数用法一样,不同数据库对应不同函数。


下篇就到函数啦~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容