
本·福达
SQL是使用最为广泛的数据库语言,几乎所有重要的DBMS都支持SQL。本书是麻省理工学院、伊利诺伊大学等众多大学的参考教材,由浅入深地讲解了SQL的基本概念和语法,涉及数据的排序、过滤和分组,以及表、视图、联结、子查询、游标、存储过程和触发器等内容,实例丰富,便于查阅。与其他同类图书不同,本书没有过多阐述数据库基础理论,而是专门针对一线软件开发人员,直接从SQLSELECT开始,讲述实际工作环境中最常用和最必需的SQL知识,实用性极强。新版对书中的案例进行了全面的更新,并增加了章后挑战题,便于读者巩固所学知识。
可恨的是为什么不同DBMS的语法不一样。本书对新手很友好,讲的很详细,上一秒纠结的点,下一秒作者就告诉你了。本书对于18课19课20课21课的讲解不深,只能了解到视图、存储过程,管理事务处理和游标具体是什么,浅尝辄止,但作为入门书个人感觉够了,整理笔记如下(可直接写入.sql文件),希望帮到你们。 -- 《SQL必知必会》第二章 检索数据 /* SELECT prod_name, prod_prIce FROM products;# 这是一条注释 -- 这也是一条注释 /* 这是一段注释 */ /* SELECT DISTINCT prod_id FROM orderitems; -- 只检索出不同的 SELECT prod_name FROM products LIMIT 5; -- 只看前五条 SELECT prod_name FROM products LIMIT 5 OFFSET 4;-- 丢掉前四行,看后面的五行 SELECT prod_name FROM products LIMIT 4,5;-- 丢掉前四行,看后面的五行 SELECT * FROM products; -- 检索表中所有的列 */ -- 《SQL必知必会》第三章 排序检索数据 /* SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price,prod_name; -- 排序数据,先按price排,一致再按name排,升序 SELECT prod_id, prod_price, prod_name FROM products ORDER BY 2, 3; -- 排序数据,从0列开始,先按照第二列排,再按照第三列排,升序 SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price DESC; # 按照 price 降序排序数据 SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price DESC,prod_name DESC; # 多个列降序必须在每个列背后加上DESC */ # 1检索2过滤3排序4限制 -- 《SQL必知必会》第四章 过滤数据 /* SELECT prod_id, prod_price, prod_name FROM products WHERE prod_price > 6 ORDER BY prod_price,prod_name; -- WHERE子句操作符 # WHERE 子句操作符: =,!=,<>,>.>=,!<,<=.!>,IS NULL, BETWEEN a AND b(包含a和b) */ -- 《SQL必知必会》第五章 高级数据过滤 /* SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id = 'BRS01' AND prod_price > 7; SELECT prod_id, prod_price, prod_name FROM products WHERE prod_price < 4 OR prod_price > 7; # WHERE 子句可以包含任意数量的 OR 和 AND , 顺序是括号>与>或; # 列出价格为10美元以上,由DLL01或BRS01 制造的所有产品 SELECT prod_name, prod_price FROM products WHERE prod_price > 10 and (vend_id = 'DLL01' OR vend_id = 'BRS01'); SELECT prod_name, prod_price FROM products WHERE vend_id IN ('DLL01','BRS01') ORDER BY prod_name; -- IN 指定条件范围 SELECT prod_name FROM products WHERE NOT vend_id = 'DLL01' ORDER BY prod_name; -- NOT 否定跟在其后的条件 */ -- 《SQL必知必会》第六章 用通配符进行过滤; /* SELECT prod_id, prod_name FROM products WHERE prod_name LIKE 'Fish%';-- 通配符'%'表示任何字符出现任意次数 SELECT prod_id, prod_name FROM products WHERE prod_name LIKE '__ inch teddy bear';-- 通配符'_'只匹配单个字符 -- 通配符'[]'指定一个字符集,必须匹配所在位置的一个字符, MYSQL 不支持 # 不要过度使用通配符,用通配符尽量不放在开头 */ -- 《SQL必知必会》第七章 创建计算字段; /* SELECT concat(RTRIM(vend_name),'(',RTRIM(vend_country),')') FROM vendors ORDER BY vend_name; -- MYSQL用 concat()函数拼接,RTRIM去除右空格 SELECT prod_name AS pname FROM products; -- 别名 AS SELECT prod_id, quantity, item_price, quantity * item_price AS totalprice FROM orderitems where order_num = 20008; -- totalprice 是一个计算字段除了* 还有+,-,/ */ -- 《SQL必知必会》第八章 使用函数处理数据; /* -- 函数upper()将文本转换为大写,lower()转小写 -- MYSQL中提取字符串用substring()函数,用法为substring(str,pos,len)从str的pos位置开始提取长为len的字符串,pos可选 SELECT cust_name, cust_contact FROM customers WHERE soundex(cust_contact) = soundex('Michael Green');-- soundex()函数用于发音检索 SELECT order_num FROM orders WHERE year(order_date) = 2020; -- MYSQL 用year()函数提取年份,month()函数提取月份 -- 数值处理函数 abs(), cos(), exp(), pi()返回Π的值, sin(), sqrt(), tan(). */ -- 《SQL必知必会》第九章 汇总数据; # SQL的五个聚集函数 avg()返回某列平均值,count()行数,,max()最大值,min()最小值,sum()某列值之和; -- 《SQL必知必会》第十章 分组数据; /* SELECT vend_id, COUNT(*) AS num_prods FROM products GROUP BY vend_id; -- 按照 vend_id分组并计算每组行数,GROUP BY中列出的必须是检索列,不能是聚集函数 SELECT cust_id, count(*) AS orders FROM orders GROUP BY cust_id HAVING COUNT(*) >= 2 -- WHERE对行过滤, HAVING对组过滤 */ -- 《SQL必知必会》第十一章 使用子查询; /* SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'RGAN01'); -- 子查询,可以子查询里面再有子查询 # 子查询的SELECT语句只能返回单个列 SELECT cust_name, cust_state,(SELECT count(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name; */ -- 《SQL必知必会》第十二章 联结(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 products INNER JOIN vendors ON products.vend_id = vendors.vend_id -- 使用内联结创建联结 */ -- 《SQL必知必会》第十三章 创建高级联结; /* SELECT cust_name, cust_contact FROM customers AS C, orders AS O, orderitems AS OI WHERE C.cust_id = O.cust_id AND O.order_num = OI.order_num AND prod_id = 'RGAN01'; -- 对表使用别名 # 自联结 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'; # 自然联结 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'; # 外联结 SELECT customers.cust_id, orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id; -- OUT JOIN 指定了联结类型时外联结,LEFT指包含左表-orders的所有行 */ -- 《SQL必知必会》第十四章 组合查询; /* SELECT cust_name, cust_contact, cust_email FROM customers WHERE cust_state IN ('IL','IN','MI') UNION -- UNION指示DBMS执行这两条SELECT语句,并把输出组合成一个查询结果集 SELECT cust_name, cust_contact, cust_email FROM customers WHERE cust_name = 'Fun4All'; # UNION 默认取消重复的行,可用 UNION ALL不取消重复行 # ORDER BY 只能放在最后一个SELECT语句的最后 */ -- 《SQL必知必会》第十五章 插入数据; /* INSERT INTO customers VALUES(1000000006, 'Toy Land', '123 Any Street', 'New York', 'NY', '11111', 'USA', NULL, NULL); -- 在表customers中插入完整的的行 INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)-- 指定列名插入更安全 VALUES (1000000006, 'Toy Land', '123 Any Street', 'New York', 'NY', '11111', 'USA', NULL, NULL); # 在表的定义允许的情况下,只给出一行部分列名插入数据,就能插入部分行了(省略某几列) INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) SELECT cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email FROM CustNew;-- INSERT SELECT语句合并表,将custnew表合并到customers中 # 复制表 CREATE TABLE customers_new AS SELECT * FROM customers; -- 复制一个customers表,名为customers_new */ -- 《SQL必知必会》第十六章 更新和删除数据; /* # 更新/删除数据 UPDATE/DELETE 语句,有更新/删除特定行和更新/删除所有行两种更新方式 UPDATE Customers -- 要更新的表 SET cust_email = '[email protected]' -- 列名和新值 WHERE cust_id = 1000000005; -- 过滤条件 # 更新多个列 UPDATE Customers SET cust_contact = 'Sam Roberts', cust_email = '[email protected]' WHERE cust_id = 1000000006; # 删除一行 DELETE FROM Customers WHERE cust_id = 1000000006; */ -- 《SQL必知必会》第十七章 创建操纵表; # 创建表 /* 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, prod_desc VARCHAR(1000) NULL -- NULL为默认设置,可省略,如果不指定NOT NULL,就是NULL );*/ /* CREATE TABLE OrderItems ( order_num INTEGER NOT NULL, order_item INTEGER NOT NULL, prod_id CHAR(10) NOT NULL, quantity INTEGER NOT NULL DEFAULT 1, -- 如果没给具体值就默认为1 item_price DECIMAL(8,2) NOT NULL -- 对于日期,设定默认为当前日期语句为 DEFAULT CURRENT_DATE() );*/ # 更新表 /* ALTER TABLE Vendors ADD vend_phone CHAR(20); -- 给vendors表增加一个名为vendor_phone的列 ALTER TABLE Vendors DROP COLUMN vend_phone; -- 给vendors 表删除vend_phone列 DROP TABLE custcopy; -- 删除custcopy表*/ -- 《SQL必知必会》第十八章 使用视图; # 视图是虚拟的表,本身不包含数据,只包含在需要使用时执行动态检索的查询语句 # 创建视图 /*CREATE VIEW ProductCustomers AS SELECcust_name, cust_contact, prod_id FROM Customers, Orders, OrderItems WHERE Customers.cust_id = Orders.cust_id AND OrderItems.order_num = Orders.order_num;*/ # 调用视图 SELECT cust_name, cust_contact FROM ProductCustomers WHERE prod_id = 'RGAN01'; -- 《SQL必知必会》第十九章 使用存储过程; # 简单来说,存储过程就是为以后使用而保存的一条或多条SQL语句。类似于python的函数 # 使用存储过程有三个主要的好处,即简单、安全、高性能。 -- 《SQL必知必会》第二十章 管理事物处理; # 使用事务处理(transaction processing),通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性。 # COMMIT用于在执行一系列操作不出错时提交语句 # ROLLBACK 相当于游戏中的存档点 -- 《SQL必知必会》第二十一章 使用游标; # 游标(cursor)是一个存储在DBMS服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。 -- 《SQL必知必会》第二十二章 高级SQL特性; # 约束 -- 主键,是一种特殊的约束,定义主键的方法可以是在创建表时定义它也可以是更新表操作中用CONSTRAINT语法 -- 外键,是表中的一列,其值必须列在另一表的主键中。外键是保证引用完整性的极其重要部分。 # 定义外键的方法 /* 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) );*/ -- 唯一约束,保证一列(或一组列)中的数据是唯一的。 -- 检查约束用来保证一列(或一组列)中的数据满足一组指定的条件。 /* 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 );*/ # 索引,用来排序数据以加快搜索和排序操作的速度 # 触发器,是特殊的存储过程,它在特定的数据库活动发生时自动执行。 # (最后吐槽一下微信读书,我先把附录看完之后,微信读书就一直阅读进度100%,改为在读,他过一会还是自动跳转为已读完,感觉是不是可以在每个章节随机放一个触发器避免这个问题)
SQL必知必会(第5版) ◆ 1.1 数据库基础 >> 主键通常定义在表的一列上,但并不是必须这么做,也可以一起使用多个列作为主键。在使用多列作为主键时,上述条件必须应用到所有列,所有列值的组合必须是唯一的 ◆ 2.4 检索所有列 >> 但检索不需要的列通常会降低检索速度和应用程序的性能。 >> 使用通配符有一个大优点。由于不明确指定列名(因为星号检索每一列),所以能检索出名字未知的列 ◆ 2.5 检索不同的值 >> 办法就是使用DISTINCT关键字,顾名思义,它指示数据库只返回不同的值。 >> DISTINCT关键字作用于所有的列,不仅仅是跟在其后的那一列。 ◆ 2.6 限制结果 >> 可以用TOP关键字来限制最多返回多少行 >> FETCH FIRST 5 ROWS ONLY就会按字面的意思去做的(只取前5行) >> 如果你使用Oracle,需要基于ROWNUM(行计数器)来计算行 >> 如果你使用MySQL、MariaDB、PostgreSQL或者SQLite,需要使用LIMIT子句,像这样: >> LIMIT 5 OFFSET 5指示MySQL等DBMS返回从第5行起的5行数据。第一个数字是检索的行数,第二个数字是指从哪儿开始。 >> MySQL、MariaDB和SQLite可以把LIMIT 4 OFFSET 3语句简化为LIMIT 3,4。使用这个语法,逗号之前的值对应OFFSET,逗号之后的值对应LIMIT(反着的,要小心)。 >> SQL虽然通常都有相当一致的实现,但你不能想当然地认为它总是这样。非常基本的语句往往是相通的,但较复杂的语句就不同了 ◆ 2.7 使用注释 >> 注释使用--(两个连字符)嵌在行内。——之后的文本就是注释 >> 注释从/*开始,到*/结束,/*和*/之间的任何内容都是注释。 ◆ 3.1 排序数据 >> 关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有任何意义。 >> 在指定一条ORDER BY子句时,应该保证它是SELECT语句中最后一条子句。如果它不是最后的子句,将会出错。 >> 通常,ORDER BY子句中使用的列将是为显示而选择的列。但是,实际上并不一定要这样,用非检索的列排序数据是完全合法的。 ◆ 6.1 LIKE操作符 >> 根据DBMS的不同及其配置,搜索可以是区分大小写的。如果区分大小写,则’fish%’与Fish bean bag toy就不匹配。 ◆ 6.2 使用通配符的技巧 >> 通配符搜索一般比前面讨论的其他搜索要耗费更长的处理时间 >> 不要过度使用通配符 >> 在确实需要使用通配符时,也尽量不要把它们用在搜索模式的开始处。把通配符置于开始处,搜索起来是最慢的。 >> 仔细注意通配符的位置 ◆ 7.2 拼接字段 >> 将值联结到一起(将一个值附加到另一个值)构成单个值。 >> 为正确返回格式化的数据,必须去掉这些空格。这可以使用SQL的RTRIM()函数来完成 ◆ 9.1 聚集函数 >> AVG()只能用值列的平均值,而且列名必须作为函数参数给出。为了获得多个列的平均值,必须使用多个AVG()函数 >> AVG()函数忽略列值为NULL的行。 >> SUM()函数忽略列值为NULL的行。 ◆ 9.2 聚集不同值 >> 在使用了DISTINCT后,此例子中的avg_price比较高,因为有多个物品具有相同的较低价格。排除它们提升了平均价格。 >> 如果指定列名,则DISTINCT只能用于COUNT()。DISTINCT不能用于COUNT(*)。类似地,DISTINCT必须使用列名,不能用于计算或表达式。 ◆ 9.3 组合聚集函数 >> 在指定别名以包含某个聚集函数的结果时,不应该使用表中实际的列名 ◆ 10.2 创建分组 >> GROUP BY子句指示DBMS分组数据,然后对每个组而不是整个结果集进行聚集。 >> GROUP BY子句中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数) >> 如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名 >> 除聚集计算语句外,SELECT语句中的每一列都必须在GROUP BY子句中给出 >> GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。 ◆ 10.3 过滤分组 >> 唯一的差别是,WHERE过滤行,而HAVING过滤分组。 >> 学过的这些有关WHERE的所有技术和选项都适用于HAVING。它们的句法是相同的,只是关键字有差别。 >> WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。 ◆ 10.4 分组和排序 >> 一般在使用GROUP BY子句时,应该也给出ORDER BY子句。这是保证数据正确排序的唯一方法。千万不要仅依赖GROUP BY排序数据。 ◆ 11.2 利用子查询进行过滤 >> 在SELECT语句中,子查询总是从内向外处理。 ◆ 11.3 作为计算字段使用子查询 >> 要对每个顾客执行COUNT(*),应该将它作为一个子查询 >> SELECT cust_name, cust_state, (SELECT COUNT(*) FROM Orders WHERE Orders.cust_id = Customers.cust_id) AS orders FROM Customers ORDER BY cust_name; >> 如果在SELECT语句中操作多个表,就应使用完全限定列名来避免歧义。 ◆ 12.1 联结 这里其实就是说数据库要满足基本的数据范式(一般数据库的设计满足第三范式即可) 范式的好处是:使编程相对简单,数据量更小,更适合放入内存,更新更快,只需更新更少的数据。更少的冗余数据意味着更少地需要GROUP、DISTINCT之类的操作。不利之处是查询会变得更加复杂,查询时需要更多连接(JOIN)操作,一些可以复合索引的列由于范式化的需要被分布到了不同的表中,导致索引策略不佳。 我们日常输出的数据呈现清单报表的时候,又需要一定程度地反范式,通过增加冗余数据或通过分组数据来优化数据库读取性能的过程。 >关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过某些共同的值互相关联(所以才叫关系数据库)。 >> 关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过某些共同的值互相关联(所以才叫关系数据库)。 ◆ 12.2 创建联结 >> 相应的笛卡儿积不是我们想要的。这里返回的数据用每个供应商匹配了每个产品,包括了供应商不正确的产品(即使供应商根本就没有产品)。 >> SQL不限制一条SELECT语句中可以联结的表的数目。创建联结的基本规则也相同。 >> 不要联结不必要的表。联结的表越多,性能下降越厉害。 ◆ 14.2 创建组合查询 >> UNION指示DBMS执行这两条SELECT语句,并把输出组合成一个查询结果集。 >> UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过,各个列不需要以相同的次序列出)。 >> 事实上,如果想返回所有的匹配行,可使用UNION ALL而不是UNION。 >> 如果确实需要每个条件的匹配行全部出现(包括重复行),就必须使用UNION ALL,而不是WHERE。 >> SELECT语句的输出用ORDER BY子句排序。在用UNION组合查询时,只能使用一条ORDER BY子句,它必须位于最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句。 ◆ 14.4 挑战题 SELECT语句的输出用ORDER BY子句排序。在用UNION组合查询时,只能使用一条ORDER BY子句,它必须位于最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句。 ◆ 15.1 数据插入 >> 这个例子将一个新顾客插入到Customers表中。存储到表中每一列的数据在VALUES子句中给出,必须给每一列提供一个值。如果某列没有值,如上面的cust_contact和cust_email列,则应该使用NULL值(假定表允许对该列指定空值)。各列必须以它们在表定义中出现的次序填充。 >> 表名后的括号里明确给出了列名。在插入行时,DBMS将用VALUES列表中的相应值填入列表中的对应项。VALUES中的第一个值对应于第一个指定列名,第二个值对应于第二个列名,如此等等。 >> 因为提供了列名,VALUES必须以其指定的次序匹配指定的列名,不一定按各列出现在表中的实际次序。其优点是,即使表的结构改变,这条INSERT语句仍然能正确工作。 >> 不要使用没有明确给出列的INSERT语句。给出列能使SQL代码继续发挥作用,即使表结构发生了变化。 >> 不管使用哪种INSERT语法,VALUES的数目都必须正确。如果不提供列名,则必须给每个表列提供一个值;如果提供列名,则必须给列出的每个列一个值。否则,就会产生一条错误消息,相应的行不能成功插入 >> 如果表的定义允许,则可以在INSERT操作中省略某些列。省略的列必须满足以下某个条件。 ❑ 该列定义为允许NULL值(无值或空值)。 ❑ 在表定义中给出默认值。这表示如果不给出值,将使用默认值。 >> INSERT还存在另一种形式,可以利用它将SELECT语句的结果插入表中,这就是所谓的INSERT SELECT ◆ 16.1 更新数据 >> 要删除某个列的值,可设置它为NULL ◆ 16.2 删除数据 >> DELETE删除整行而不是删除列。要删除指定的列,请使用UPDATE语句。 ◆ 16.3 更新和删除的指导原则 >> 在UPDATE或DELETE语句使用WHERE子句前,应该先用SELECT进行测试,保证它过滤的是正确的记录,以防编写的WHERE子句不正确。 ◆ 17.1 创建表 >> 利用CREATE TABLE创建表,必须给出下列信息:❑ 新表的名字,在关键字CREATE TABLE之后给出;❑ 表列的名字和定义,用逗号分隔;❑ 有的DBMS还要求指定表的位置。 >> 列名(它在表中必须是唯一的) 为了防止新表表名已经存在导致的报错,可以在建表示加上if not exists,写成: create table 【if not exists】 表名( 字段名 字段类型 【约束】, 字段名 字段类型 【约束】, 。。。 字段名 字段类型 【约束】 ) >在创建新的表时,指定的表名必须不存在,否则会出错。 >> 在创建新的表时,指定的表名必须不存在,否则会出错。 >> 主键是其值唯一标识表中每一行的列。只有不允许NULL值的列可作为主键,允许NULL值的列不能作为唯一标识 >> NULL值是没有值,不是空字符串 >> 空字符串是一个有效的值,它不是无值 ◆ 17.2 更新表 理想情况下,不要在表中包含数据时对其进行更新。应该在表的设计过程中充分考虑未来可能的需求,避免今后对表的结构做大改动。 1.添加列 alter table 表名 add column 列名 类型 【first|after 字段名】; 2.修改列的类型或约束 alter table 表名 modify column 列名 新类型 【新约束】; 3.修改列名 alter table 表名 change column 旧列名 新列名 类型; 4 .删除列 alter table 表名 drop column 列名; 5.修改表名 alter table 表名 rename 【to】 新表名; >17.2 更新表 >> 复杂的表结构更改一般需要手动删除过程,它涉及以下步骤: (1) 用新的列布局创建一个新表; (2) 使用INSERT SELECT语句(关于这条语句的详细介绍,请参阅第15课)从旧表复制数据到新表。有必要的话,可以使用转换函数和计算字段; (3) 检验包含所需数据的新表; (4) 重命名旧表(如果确定,可以删除它); (5) 用旧表原来的名字重命名新表; (6) 根据需要,重新创建触发器、存储过程、索引和外键。 >> 数据库表的更改不能撤销,如果增加了不需要的列,也许无法删除它们。类似地,如果删除了不应该删除的列,可能会丢失该列中的所有数据。 ◆ 17.3 删除表 >> 许多DBMS允许强制实施有关规则,防止删除与其他表相关联的表。在实施这些规则时,如果对某个表发布一条DROP TABLE语句,且该表是某个关系的组成部分,则DBMS将阻止这条语句执行,直到该关系被删除为止。如果允许,应该启用这些选项,它能防止意外删除有用的表。 ◆ 18.1 视图 视图是mysql5.1版本出现的新特性,视图本身是一个虚拟表,它的数据来自于表,通过执行时动态生成。 好处: 1、简化sql语句 2、提高了sql的重用性 3、保护基表的数据,提高了安全性 二、创建 create view 视图名 as 查询语句; 三、修改 方式一: create or replace view 视图名 as 查询语句; 方式二: alter view 视图名 as 查询语句 四、删除 drop view 视图1,视图2,...; 五、查看 desc 视图名; show create view 视图名; 六、使用 1.插入 insert 2.修改 update 3.删除 delete 4.查看 select 注意:视图一般用于查询的,而不是更新的,所以具备以下特点的视图都不允许更新 ①包含分组函数、group by、distinct、having、union、 ②join ③常量视图 ④where后的子查询用到了from中的表 ⑤用到了不可更新的视图 >18.1 视图 >> 视图的一些常见应用。 ❑ 重用SQL语句。 ❑ 简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道其基本查询细节。 ❑ 使用表的一部分而不是整个表。 ❑ 保护数据。可以授予用户访问表的特定部分的权限,而不是整个表的访问权限。❑ 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。创建视图之后,可以用与表基本相同的方式使用它们。可以对视图执行SELECT操作,过滤和排序数据,将视图联结到其他视图或表,甚至添加和更新数据 >> 关于视图创建和使用的一些最常见的规则和限制。 ❑ 与表一样,视图必须唯一命名(不能给视图取与别的视图或表相同的名字)。 ❑ 对于可以创建的视图数目没有限制。 ❑ 创建视图,必须具有足够的访问权限。这些权限通常由数据库管理人员授予。 ❑ 视图可以嵌套,即可以利用从其他视图中检索数据的查询来构造视图。所允许的嵌套层数在不同的DBMS中有所不同(嵌套视图可能会严重降低查询的性能,因此在产品环境中使用之前,应该对其进行全面测试)。 ❑ 许多DBMS禁止在视图查询中使用ORDER BY子句。 ❑ 有些DBMS要求对返回的所有列进行命名,如果列是计算字段,则需要使用别名(关于列别名的更多信息,请参阅第7课)。 ❑ 视图不能索引,也不能有关联的触发器或默认值。 ❑ 有些DBMS把视图作为只读的查询,这表示可以从视图检索数据,但不能将数据写回底层表。详情请参阅具体的DBMS文档。 ❑ 有些DBMS允许创建这样的视图,它不能进行导致行不再属于视图的插入或更新。例如有一个视图,只检索带有电子邮件地址的顾客。如果更新某个顾客,删除他的电子邮件地址,将使该顾客不再属于视图。 ◆ 18.2 创建视图 >> SELECT约束全部适用 >> 用视图过滤不想要的数据 >> 在简化计算字段的使用上,视图也特别有用 >> 视图非常容易创建,而且很好使用。正确使用,视图可极大地简化复杂数据的处理。 ◆ 18.3 小结 >> 视图为虚拟的表。它们包含的不是数据而是根据需要检索数据的查询。视图提供了一种封装SELECT语句的层次,可用来简化数据处理,重新格式化或保护基础数据。
阅读速度5000字/分钟 1、本书主题:介绍SQL的基本概念和语法 2、速读建议:业余人士大致浏览即可。 有人会觉得这些内容上网查也能知道, 1、网上信息很杂乱,找到需要的内容费时费力; 2、不要高估自己的定力,可能上网中途就去干别的了; 3、网上的信息真假难辨; 提供权威书籍系统学习基础知识,效率比上网搜更高。 确实网上有个别解读浅显易懂,也很有趣。 但别拣了芝麻丢了西瓜。 本书含金量高,值得推荐。
本科的时候学过数据库,这次也是先看了一些视频课程进行回顾,才又来看书再巩固一下。内容很基础,读起来很快,确实是很适合小白了,有助于提升学习信心。提供的网站上有习题答案,用起来还不错。不过有挺多重要的内容一笔带过,比如索引,还有的甚至根本没提到,比如锁。
真真的入门级别,已经入门的话,不建议看。 UNION操作符:当你需要从多个表中获取相似的数据并将其合并为一个结果集时,UNION 是非常有用的。 事务处理是一种机制,用来管理必须成批执行的SQL操作,保证数据库不包含不完整的操作结果。 需要在检索出来的行中前进或后退一行或多行,这就是游标的用途所在。 触发器是特殊的存储过程,它在特定的数据库活动发生时自动执行。 1确保数据正确。比喻:想象你在填写一张表格,有人会在你填完后立即检查你的信息是否正确。如果发现错误,他们会告诉你并阻止你提交。 实际应用:当你在某个表中插入或更新数据时,触发器会自动检查这些数据是否符合特定的规则。如果不符,它可以阻止这些数据被保存。 2记录操作日志。比喻:就像你在银行存取款时,银行会自动记录你的每一笔交易。 实际应用:每当表中的数据发生变化(如插入、更新或删除),触发器可以自动把这些变化记录到另一个表中,以便日后查看和审计。 3自动执行任务。比喻:就像你设定了一条规则,每当你完成一项任务,系统会自动给你发一封奖励邮件。 实际应用:当某个事件发生时(如订单状态变为“已发货”),触发器可以自动执行一些操作,比如发送邮件通知客户。 4保持数据同步。比喻:就像你在两个笔记本上做笔记,当你在一个笔记本上写了一些东西,另一个笔记本会自动同步这些内容。 实际应用:当一个表中的数据发生变化时,触发器可以自动更新另一个表中的相应数据,确保两个表的数据保持一致。
书里面具体知识点,我就不长篇累牍地在这做笔记了,各位自行阅读即可。重点讲下,个人认为这本书适合什么人看,以及能否学会的观点。先说个人水平,我是个文科生,且零基础,我通过B站白嫖课自学了sql的萌新,属于刚新鲜出炉学会sql的萌新。看这本书原因和各位一样,无非就是sql工具书销售榜一都是它,以及大佬们都墙裂推荐入行小白必读,慕名而来读的。读完此书后,有几个看法: 一、这本书对于我这个零基础刚学会sql的萌新来说,都太过容易了,是真的完全没难度,知识点比较浅,我看这本书就当作复习和巩固知识点了。 二、这本书知识虽然浅,但内容很精华又核心,非常适合也非常建议,小白阅读,就算没学过sql的人,只要你掌握了高中基本数学的思维,和初中英语词汇量,都可以读得懂这本书,完全不用担心。 三、这本书虽然读完了,你入门也只是入了一半,因为学会一门语言最好的方法是实践,光看是很难把一个知识真的掌握的。建议读完此书去牛客网把题都刷完。对了,牛客网还有专门的篇章就是这本书的配套课后习题,也建议初学者边看边刷题。实践与理论结合,这个sql的基础门算是入的了。 没想到这个几年前随手写的评论,还是挺多网友点赞的。那我补充多第四点哈 四、这本书核心知识基本上具备了,但由于这本书出版时间还是比较久远的,因此该本唯一缺漏的重点知识是窗口函数。 窗口函数是日常业务的重点知识,学习这本书的网友们,需要自己找这块知识补全哈。
对我而言,这本书最大的价值不是记住了多少语法,而是两点认知: 1. SQL 的本质是“提问” 写 SQL 的过程,其实是在把业务问题翻译成数据库能理解的问题。语法只是工具,逻辑思维才是核心。 2. 克制与清晰比炫技更重要 能用简单查询解决的问题,就不要写成多层嵌套的“天书 SQL”。可读性、可维护性,往往比“看起来很厉害”更重要。 《SQL必知必会》是一本“小而美”的 SQL 入门书,它不一定让你成为专家,但一定能让你真正会用 SQL。
微信读书读完的第377本书,《SQL必知必会《第5版》》。经典SQL书籍,介绍不同版本软件,怎样创立数据库、表格、插入数据、修改表格、修改数据、查询数据(select from、where、group by、having、order by、join、union、子查询、常见函数等)、存储、索引、触发器等。本书并没有涉及到窗口函数。可以在牛客网,实操练习“必知必会”部分。
今天花了一天时间,从头到尾仔细看了一遍,下午五点钟看完。本书重点介绍了SELECT语句用法,后面章节的高级用法只是做了概念性的介绍,可以作为入门级别的学习,提升学习不太适合,像一些高级用法递归与开窗函数等都没有讲。
看到十八课。这本书太浅了,只能说是摸着门边,都不能说是入门。说是浅吧,但好像也不能说是非常系统,像是数据类型这种东西也不放在正文要放在附录,很多底层的东西都没搭建起来(也可能是sql本身的特性吧)。像是习惯写R的,新建一个列用来辅助计算很正常,但是sql尽量避免对数据的直接操作,所以会导致思维习惯上差别有点大,类似这种的点也没完全点出来。 个人认为有点其他语言基础的直接去看cheat sheet可能都好过在这本上费时间…… btw真是越写题越火大……