目录
1. 第十二课 查询的执行顺序
1.1 知识点
讨论在了解所有查询语句的基础上,如何将查询语句进行完整的组合。整体书序结构如下所示:
完成SELECT查询
SELECT DISTINCT column, AGG_FUNC(column_or_expression), …
FROM mytable
JOIN another_table
ON mytable.column = another_table.column
WHERE constraint_expression
GROUP BY column
HAVING constraint_expression
ORDER BY column ASC/DESC
LIMIT count OFFSET COUNT;
即:每个查询都从查找数据库中需要的数据开始,然后将这些数据过滤成可以尽快处理和理解的内容。因为查询的每个部分都是按顺序执行的,所以了解执行顺序非常重要,可以知道哪些结果可以快速访问。下面对执行顺序依次进行讲解:
(1)FROM和JOIN
首先执行该FROM子句和后续步骤JOIN以确定正在查询的数据的总工作集。这包括此子句中的子查询,并且可以导致在引擎盖下创建临时表,其中包含要连接的表的所有列和行。
(2)WHERE
一旦我们拥有了总工作数据集,就会将第一遍WHERE
约束应用于各个行,并且丢弃不满足约束的行。每个约束只能直接从FROM
子句中请求的表访问列。SELECT
查询部分中的别名在 大多数数据库中都不可访问,因为它们可能包含依赖于尚未执行的查询部分的表达式。
(3)GROUP BY
WHERE之
后,应用约束后的其余行将根据GROUP BY
子句中指定的列中的公共值进行分组。作为分组的结果,只有与该列中的唯一值一样多的行。隐含地,这意味着只有在查询中具有聚合函数时才需要使用它。
(4)HAVING
如果查询具有GROUP BY
子句,则HAVING
子句中的约束将应用于分组行,丢弃不满足约束的分组行。与该WHERE
子句一样,在大多数数据库中也无法从此步骤访问别名。
(5)SELECT
SELECT
最后计算查询部分中的任何表达式.
(6)DISTINGCT
在剩余的行中,标记为列的具有重复值的DISTINCT
行将被丢弃。
(7)
ORDER BY
如果ORDER BY
子句指定了一个订单,那么这些行将按指定的数据按升序或降序排序。由于SELECT
已经计算了查询部分中的所有表达式,因此可以在此子句中引用别名。
(8)
LIMIT
/OFFSET
最后,落入由所指定的范围之外的行LIMIT
和OFFSET
从查询返回的被丢弃,在离开最后行的集合。
小结:并非每个查询都需要包含上面列出的所有部分,但SQL的灵活性的一部分原因在于它允许开发人员和数据分析人员快速操作数据而无需编写额外的代码,所有这些都只是使用上述条款。
1.2 练习题
#1. 查找每个导演指导的电影数量
my:
SELECT title,director,count(*) FROM movies
group by director;
Sy:
SELECT director, COUNT(id) as Num_movies_directed
FROM movies
GROUP BY director;
#2. 查找可归因于每位董事的国内和国际销售总额
my 错误:
SELECT title,director, (domestic_sales + international_sales) AS TOTAL_SALES
FROM movies
RIGHT JOIN Boxoffice ON Movie.Id = Boxoffice.Movie_id
group by director;
最正确的:
SELECT director, SUM(domestic_sales + international_sales) as Cumulative_sales_from_all_movies
FROM movies
INNER JOIN boxoffice
ON movies.id = boxoffice.movie_id
GROUP BY director;
2. 第十三课 插入行
这节开始学习SQL模式以及如何添加亲数据的知识。
2.1 知识点
模式:数据库中的表被描述为一组二维列表,列表是属性,行表示实体中的实例,SQL中,数据库中的模式描述了每个表的结构,以及表的每列可以包含的数据类型。
插入新数据
将数据插入数据库时,需要使用一个INSERT语句,该语句声明要写入的表,正在填充的数据列以及要插入法的一行或多行数据。通常,插入的每行数据都应该包含表中每个相应列的值,可以按顺序列出多个行,或一次插入多行。
插入包含所有列值的语句
INSERT INTO mytable
VALUES (value_or_expr, another_value_or_expr, …),
(value_or_expr_2, another_value_or_expr_2, …),
…;
在一些情况下,如果数据不完整且表中包含支持默认值的列,则可以通过显示指定行来插入仅包含数据列的行。
插入包含特定列的语句
INSERT INTO mytable
(column, another_column, …)
VALUES (value_or_expr, another_value_or_expr, …),
(value_or_expr_2, another_value_or_expr_2, …),
…;
在这些情况下,值的数量需要与指定的列数相匹配。尽管这是一个更冗长的写法陈述,但以这种方式插入值具有向前兼容的好处。例如,如果使用默认值向表中添加新列,则不会INSERT
更改硬编码语句以适应该更改。
此外,可以将数学和字符串表达式与您要插入的值一起使用。
这有助于确保插入的所有数据都以某种方式格式化。
例使用表达式插入语句
INSERT INTO boxoffice
(movie_id, rating, sales_in_millions)
VALUES (1, 9.9, 283742034 / 1000000);
2.2 练习题
#1.将工作室的新作品“ 玩具总动员4”添加到电影列表中(您可以使用任何导演)
INSERT INTO MOVIE
VALUES(4,"Toy Story 4","PETER",2018,98)
#2.玩具总动员4已经获得好评!它的评分为8.7,国内为3.4亿,国际为2.7亿。将记录添加到BoxOffice表中。
INSERT INTO boxoffice VALUES (4, 8.7, 340000000, 270000000);
3. 第十四课 更新行
3.1 知识点
更新现有数据,使用UPDATA语句来完成,与INSERT 语句相似,必须精确指定要更新的表,列和行,此外,更新的数据必须与模式中列的数据类型相匹配。
使用值更新语句
UPDATE mytable
SET column = value_or_expr,
other_column = another_value_or_expr,
…
WHERE condition;
该语句通过获取多个列/值对,并将这些更改应用于满足WHERE
子句中约束的每一行。
注意:首先编写约束并在SELECT
查询中对其进行测试,以确保更新正确的行,然后再写入列/值对进行更新。
3.2 练习题
#1.A Bug's Life的导演不正确,实际上是由John Lasseter执导的
MY:运行不成功,但是觉得没毛病
UPDATA movies
SET DIRECTOR = "John Lasseter"
WHERE TITLE= "A Bug's Life ";
正确的:
UPDATE movies
SET director = "John Lasseter"
WHERE id = 2;
#2. 玩具总动员2发布的那一年是不正确的,它实际上是在1999年发布的
UPDATE movies
SET year = 1999
WHERE id = 1;
#3.玩具总动员8的标题和导演都不正确!标题应为“玩具总动员3”,由Lee Unkrich执导
UPDATE movies
SET title = "Toy Story 3",director="Lee Unkrich"
WHERE id = 11;
4. 第15课 删除行
4.1 知识点
当需要从数据库中的表中删除数据时,可以使用一个DELETE
语句来描述要执行的表,以及要通过该WHERE
子句删除的表的行。
删除带条件的语句
DELETE FROM mytable
WHERE condition;
如果决定省略WHERE
约束,则删除所有行,这是一种快速简便的方法来彻底清除表(如果是有意的)。
注意:与UPDATE
上一课中的语句一样,建议SELECT
首先在查询中运行约束, 以确保删除正确的行。没有适当的备份或测试数据库,很容易不可撤销地删除数据,因此请始终阅读您的DELETE
语句两次并执行一次。
4.2 练习题
#1. 这个数据库太大了,让我们删除2005年之前发布的所有电影。
DELETE FROM movies
where year < 2005;
#2.Andrew Stanton也离开了工作室,所以请删除他指导的所有电影。
DELETE FROM movies
where director="Andrew Stanton";