大学期间学过数据库相关的知识,无奈几年下来能吃到肚子里的都吃进去了,留在脑子里的恐怕没多少了,其实之前也没有认认真真的学习过数据库,全靠实践中一点点查,还好也不算晚,看一本非常基础但是比较全面的基础书来补一补N多年前的知识,就当是复习笔记吧! 很遗憾的一点是在这本书的读书笔记里面我不会太过详细的记录具体的语法,更多的是回顾,如若不详细,还请各位移步原著去通读一遍!但也希望与我有益的同时帮助到您!
Xmind脑图下载
目录
一 了解数据库SQL
二 检索数据
三 排序检索数据
四 过滤数据
五 高级数据过滤
六 通配符进行过滤
七 创建计算字段
八 使用数据处理函数
九 汇总数据
十 分组数据
十一 使用子查询
十二、联结表&高级联结表
十四、组合查询(并UNION、符合查询)
十五、数据插入
十六、更新和删除数据
十七、创建和操纵表
十八、使用视图
十九、使用存储过程
二十、管理事务处理
二十一、使用游标(cursor)
二十二 、高级SQL特性
思维导图
SELECT PROD_NAME
FROM Product;
SELECT prod_id, prod_name, prod_price
FROM Products;
SELECT *
FROM Products;
SELECT DISTINCT vend_id
FROM Products;
SQL SERVER & Access :TOP | DB2: | Oracle:ROWNNUM | MySQL、MariaDB、PostgreSQL或者SQLite: LIMIT |
|
|
|
|
补充:
#1. 这是一条注释
/*2. 这是多
行注释*/
--3. 这是另外一种注释:从第5行起ide5行数据
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price;
#仅在多个行具有相同的prod_price值时才对产品按prod_name进行排序。如果prod_price列中所有的值都是唯一的,则不会按prod_name排序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price, prod_name;
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3;
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price DESC,prod_name; --只对prod_price列指定DESC,对prod_name列不指定
SELECT prod_name, prod_price
FROM Products
WHERE prod_price = 3.49;
|
AND 和OR组合使用时:AND优先级>OR,因此需要将OR语句用()括起来
SELECT prod_name,prod_price
FROM Products
WHERE (vend_id = 'DLL01' OR vend_id = 'BRS01')
AND prod_price >=10;
LIKE
注意:
(1)拼接字段(将值联结到一起构成单个值)
(2)执行算数计算:+、-、*、/
SQL函数不可移植;
(1)文本处理函数:
注:SOUNDEX将任何文本串转换为描述其语音表示的字母数字模式。SOUNDEX考虑了类似的发音字符和音节,使得能对字符串进行发音比较而不是字母比较。
(2)日期和时间处理函数
DATAPART()、to_date()等,不同环境语法不同;
(3)数值处理
(1)聚集函数
(2)聚集不同值:DISTINCT
警告:DISTINCT不能用于COUNT(*)
如果指定列名,则DISTINCT只能用于COUNT()。DISTINCT不能用于COUNT(*)。类似地,DISTINCT必须使用列名,不能用于计算或表达式。提示:将DISTINCT用于MIN()和MAX()
虽然DISTINCT从技术上可用于MIN()和MAX(),但这样做实际上没有价值。一个列中的最小值和最大值不管是否只考虑不同值,结果都是相同的。
(3)组合聚集函数
(1)GROUP BY
(2)过滤分组Having: where过滤行,Having过滤分组
说明:HAVING和WHERE的差别
这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。
(3)分组和排序
(4)SELECT子句顺序
(1)利用子查询进行过滤
SELECT cust_id
FROM Order
WHERE order_num IN (SELECT order_num
FROM OrderItems
WHERE prod_id = 'RGAN01');
警告::只能是单列
作为子查询的SELECT语句只能查询单个列。企图检索多个列将返回错误。
子查询常用于WHERE子句的IN操作符中,以及用来填充计算列。
(2)作为计算字段使用子查询
SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM Orders WHERE Orders.cust_id = Customers.cust_id) AS orders
FROM Customers ORDER BY cust_name;
注:子查询中的WHERE子句与前面使用的WHERE子句稍有不同,因为它使用了完全限定列名,而不只是列名(cust_id)
1. 使用别名:AS
2. 创建联结
a. 等值联结,又叫内联结(inner join)
原始:
SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;
内联结:
SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;
警告::完全限定列名--在引用的列可能出现歧义时,必须使用完全限定列名(用一个句点分隔表名和列名,eg:Vendors.vend_id)。
注意:
由没有联结条件的表关系返回的结果为笛卡儿积(叉联结(cross join))。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数,要保证所有联结都有WHERE子句,否则DBMS将返回比想要的数据多得多的数据。
b. 自联结(self-join)
提示:用自联结而不是子查询
自联结通常作为外部语句,用来替代从相同表中检索数据的使用子查询语句。虽然最终的结果是相同的,但许多DBMS处理联结远比处理子查询快得多。
子查询:
SELECT cust_id, cust_name, cust_contact
FROM Customers WHERE cust_name = (SELECT cust_name
FROM Customers
WHERE cust_contact = 'Jim Jones');
自联结:
SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name = c2.cust_name
AND c2.cust_contact = 'Jim Jones';
c.自然联结(natural join)
自然联结排除多次出现,使每一列只返回一次,迄今为止建立的每个内联结都是自然联结,很可能永远都不会用到不是自然联结的内联结.
SELECT C.*, O.order_num, O.order_date, OI.prod_id, OI.quantity, OI.item_price
FROM Customers AS C, Orders AS O, OrderItems AS OI
WHERE C.cust_id = O.cust_id
AND OI.order_num = O.order_num
AND prod_id = 'RGAN01';
d. 外联结(outer join):
联结包含了那些在相关表中没有关联行的行。这种联结称为外联结。
SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust_id = Orders.cust_id
e. 使用带聚集函数的联结
主要有两种情况需要使用组合查询:
SELECT cust_name, cust_contact, cust_email
FROM Customers WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers WHERE cust_name = 'Fun4All';
1. 插入完整/部分的行
INSERT INTO Customers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact,)
VALUES('1000000006','Toy Land','123 Any Street','New York','NY','11111','USA',NULL,);
警告:小心使用VALUES
不管使用哪种INSERT语法,VA LUES的数目都必须正确。如果不提供列名,则必须给每个表列提供一个值;如果提供列名,则必须给列出的每个列一个值。否则,就会产生一条错误消息,相应的行不能成功插入。
2.插入检索出的数据
INSERT INTO Customers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact)
SELECT cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact
FROM CustNew
说明:
INSERT SELECT与SELECT INTO
它们之间的一个重要差别是前者导出数据,而后者导入数据。
3. 从一个表复制到另一个表
SELECT *
INTO CustCopy
FROM Customers;
MariaDB、MySQL、Oracle、PostgreSQL和SQLite使用:
CREATE TABLE CustCopy AS
SELECT * FROM Customers;
1. 更新数据
UPDATE Customers
SET cust_contact = 'Sam Roberts',
cust_email = '[email protected]'
WHERE cust_id = '1000000006';
UPDATE Customers
SET cust_email = NULL
WHERE cust_id = '1000000005';
注:其中NULL用来去除cust_email列中的值。这与保存空字符串很不同(空字符串用''表示,是一个值),而NULL表示没有值。
2.删除数据
DELETE FROM Customers
WHERE cust_id = '1000000006';
1、创建表
CREATE TABLE Products
(
prod_id CHAR(10) NOT NULL,
vend_id CHAR(10) NOT NULL,
prod_name CHAR(254) NOT NULL,
prod_price DECIMAL(8,2) NOT NULL DEFAULT 10,
prod_desc VARCHAR(1000) NULL
);
提示:替换现有的表
在创建新的表时,指定的表名必须不存在,否则会出错。防止意外覆盖已有的表,SQL要求首先手工删除该表(请参阅后面的内容),然后再重建它,而不是简单地用创建表语句覆盖它。
1.1、使用NULL值
1.2.使用默认值DEFAULT
2.更新表
ALTER TABLE Vendors
ADD vend_phone CHAR(20);
DROP COLUMN vend_phone;
3.删除表
DROP TABLE CustCopy;
注:删除表(删除整个表而不是其内容)
4.重命名表
RENAME、sp_rename、ALTER TABLE(都要求指定旧表名和新表名)
视图是虚拟的表,视图本身不包含数据,因此它们返回的数据是从其他表中检索出来的,在更改这些表中的数据时,视图将返回改变过后的数据。
(1)视图的规则和限制
(2)创建视图(creat view)
说明:视图重命名
删除视图,可以使用DROP语句,其语法为DROP VIEW viewname;。
覆盖(或更新)视图,必须先删除它,然后再重新创建。
为以后的使用而存储一条或多条SQL语句的集合。
(1)什么是事务处理
事务管理用来管理必须成批执行的SQL操作,以保证数据库不包含不完整的操作结果。利用事务处理,可以保证一组数据不会中途停止,它们或者作为整体执行,或者完全不执行(除非明确指示)。
如果没有错误发生,则整组语句写到数据库表,如果发生错误,则进行回退(撤销)以恢复数据库到某个已知且安全的状态。
(2)几个术语
(3)可以回退哪些语句
可管理INSERT,UPDATE,DELETE语句,不能回退SELECT语句也不能回退CREATE,DROP操作。事务处理中可以使用这些语句,但回退时它们不被撤销。
(4)控制事务处理
在这个例子中,BEGIN TRA NSA CTION和COMMIT TRA NSA CTION语句之间的SQL必须完全执行或者完全不执行。
BEGIN TRANSACTION
...
COMMIT TRANSACTION
其他:
START、SET TRANSCATION...COMMIT、BEGIN。。。其他DBMS采用上述语法的变体。多数实现没有明确标识事务处理在何处结束。事务一直存在,直到被中断。通常,COMMITT用于保存更改,ROLLBA CK用于撤销。
1.ROLLBACK
DELETE FROM Orders;
ROLLBACK;
分析:执行DELETE操作,然后用ROLLBA CK语句撤销。
2. COMMIT
BEGIN TRANSACTION
DELETE OrderItems WHERE order_num = 12345
DELETE Orders WHERE order_num = 12345
COMMIT TRANSACTION
分析:从系统中完全删除订单12345。因为涉及更新两个数据库表Orders和OrderItems,所以使用事务处理块来保证订单
不被部分删除。最后的COMMIT语句仅在不出错时写出更改。如果第一条DELETE起作用,但第二条失败,则DELETE不会提交。
3. 保留点(占位符)
提示:可以在SQL代码中设置任意多的保留点,因为保留点越多,你就越能灵活地进行回退。
游标不是一条select语句,而是被该语句检索出来的结果集,在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或更改。
DECLARE CustCursor CURSOR
FOR
SELECT * FROM Customers
WHERE cust_email IS NULL
约束:管理如何插入或处理数据库数据的规则
主键:一种特殊约束PRIMARY KEY
CREATE TABLE Vendors
(
vend_id CHAR(10) NOT NULL PRIMARY KEY,
vend_name CHAR(50) NOT NULL,
vend_country CHAR(50) NULL
);
ALTER TABLE Vendors
ADD CONSTRAINT PRIMARY KEY (vend_id);
外键:可帮助防止意外删除,
CREATE TABLE Orders
(
order_num INTEGER NOT NULL PRIMARY KEY,
order_date DATETIME NOT NULL,
cust_id CHAR(10) NOT NULL REFERENCES Customers(cust_id)
);
ALTER TABLE Orders
ADD CONSTRAINT
FOREIGN KEY (cust_id) REFERENCES Customers (cust_id)
唯一约束:UNIQUE 唯一约束用来保证一列(或一组列)中的数据是唯一的。它们类似于主键,但存在以下重要区别。
检查约束:检查约束用来保证一列(或一组列)中的数据满足一组指定的条件。检查约束的常见用途有以下几点。
CREATE TABLE OrderItems
(
order_num INTEGER NOT NULL,
order_item INTEGER NOT NULL,
prod_id CHAR(10) NOT NULL,
quantity INTEGER NOT NULL CHECK (quantity > 0),
item_price MONEY NOT NULL
);
分析▼
ADD CONSTRAINT CHECK (gender LIKE '[MF]')
索引:,就是恰当的排序,索引必须唯一命名
CREATE INDEX prod_name_ind
ON PRODUCTS (prod_name);
- 索引改善检索操作的性能,但降低了数据插入、修改和删除的性能。在执行这些操作时,DBMS必须动态地更新索引。
- 索引数据可能要占用大量的存储空间。
- 并非所有数据都适合做索引。取值不多的数据(如州)不如具有更多可能值的数据(如姓或名),能通过索引得到那么多的好处。
- 索引用于数据过滤和数据排序。如果你经常以某种特定的顺序排序数据,则该数据可能适合做索引。
- 可以在索引中定义多个列(例如,州加上城市)。这样的索引仅在以州加城市的顺序排序时有用。如果想按城市排序,则这种索引没有用处。
触发器:触发器是特殊的存储过程,它在特定的数据库活动发生时自动执行。触发器可以与特定表上的INSERT、UPDA TE和DELETE操作(或组合)相关联。
CREATE TRIGGER customer_state
ON Customers
FOR INSERT, UPDATE
AS
UPDATE Customers
SET cust_state = Upper(cust_state)
WHERE Customers.cust_id = inserted.cust_id;
数据库安全:安全性使用SQL的GRA NT和REVOKE语句来管理,不过,大多数DBMS提供了交互式的管理实用程序,这些实用程序在内部使用GRA NT和REVOKE语句。