Task 03 基础查询与排序
Content:
- 补充Task 01中的索引(index)内容
- 补充练习最后一问:是否可以编写SQL语句来回复删除掉的表
- 查询
- 排序
- 部分练习
- 补充小白(比如我)在练习中容易出现错误的地方
Reference:
[1]GitHub - datawhalechina/wonderful-sql: Follow me,从 0 到 1 掌握 SQL,决胜秋招。
1.索引
2.如何恢复删掉的表
3.查询
3.1 利用where语句从表中筛选符合条件的语句
-- 示例
SELECT <列名>
FROM <表名>
WHERE <条件表达式>
相关说明
- 星号(*)代表全部列的意思
- 设定汉语别名时需要使用双引号(")括起来
- 在 SELECT 语句中使用 DISTINCT 可以删除重复行
- SELECT 子句中可以使用常数或者表达式
- 希望选取 NULL 记录时,需要在条件表达式中使用 IS NULL 运算符。希望选取不是 NULL 的记录时,需要在条件表达式中使用 IS NOT NULL 运算符
- 如果有逻辑运算符NOT,AND,OR和NULL时,最好用括号区分主次
- 真值表的三种值:真,假,不确定(UNKNOWN),AND优先级:假>不确定>真,OR优先级:真>不确定>假
3.2 利用聚合函数对表进行聚合查询
常用聚合函数:COUNT、SUM、AVG、MAX、MIN
-- 计算全部数据的行数(包含NULL)
SELECT COUNT(*)
FROM product;
-- 计算NULL以外数据的行数
SELECT COUNT(purchase_price)
FROM product;
-- 计算销售单价和进货单价的合计值
SELECT SUM(sale_price), SUM(purchase_price)
FROM product;
-- 计算销售单价和进货单价的平均值
SELECT AVG(sale_price), AVG(purchase_price)
FROM product;
-- MAX和MIN也可用于非数值型数据
SELECT MAX(regist_date), MIN(regist_date)
FROM product;
相关说明
- 聚合函数会将 NULL 排除在外。但 COUNT(*) 例外,并不会排除 NULL,除非是COUNT(<列名>)
- MAX/MIN 函数几乎适用于所有数据类型的列。SUM/AVG 函数只适用于数值类型的列
- 在聚合函数的参数中使用 DISTINCT,可以删除重复数据
3.3 利用GROUP BY对现有的数据分组按照某列来汇总统计
-- 示例
SELECT <列名1>,<列名2>, <列名3>, ……
FROM <表名>
GROUP BY <列名1>, <列名2>, <列名3>, ……;
相关说明
- 在 GROUP BY 子句中指定的列称为 ** 聚合键** 或者 ** 分组列 **
- NULL 会作为一组特殊数据进行处理
- 使用 COUNT 等聚合函数时,SELECT 子句中如果出现列名,只能是 GROUP BY 子句中指定的列名(也就是聚合键)
- SELECT 子句中可以通过 AS 来指定别名,但在 GROUP BY 中不能使用别名。因为在 DBMS 中,SELECT子句在 GROUP BY 子句后执行
3.4 用HAVING获得特定分组
-- 示例(利用数字筛选)
SELECT product_type, COUNT(*)
FROM product
GROUP BY product_type
HAVING COUNT(*) = 2;
相关说明
- WHERE和HAVING的区别:WHERE 子句只能指定记录(行)的条件,而不能用来指定组的条件(例如,“数据行数为 2 行”或者“平均值为 500”等)
- HAVING可以使用数字、聚合函数和 GROUP BY 中指定的列名(聚合键)
4.用ORDER BY对查询结果进行排序
-- 示例
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
ORDER BY <排序基准列1>, <排序基准列2>, ……
相关说明
- 默认为升序排列,降序排列为 DESC
- SQL 在使用SELECT 语句时的顺序为:
FROM WHERE GROUP BY HAVING SELECT ORDER BY
5.部分练习
3.1 编写一条 SQL 语句,从 product(商品)表中选取出“登记日期(regist_date)在 2009 年 4 月 28 日之后”的商品,查询结果要包含 product_name 和 regist_date 两列
3.2 请说出对 product 表执行如下 3 条 SELECT 语句时的返回结果
SELECT *
FROM product
WHERE purchase_price = NULL;
从product表中取出“purchase_price为空”的所有商品,查询结果包含这些商品的所有信息。
SELECT *
FROM product
WHERE purchase_price <> NULL;
从product表中取出“purchase_price非空”的所有商品,查询结果包含这些商品的所有信息。
SELECT *
FROM product
WHERE purchase_name > NULL;
从product表中取出“purchase_name非空”的所有商品,查询结果包含这些商品的所有信息。
3.3 使用SELECT 语句能够从 product 表中取出“销售单价(sale_price)比进货单价(purchase_price)高出 500 日元以上”的商品
SELECT product_name,sale_price,purchase_price
FROM product
WHERE NOT sale_price-purchase_price<500;
/*
或
WHERE sale_price+purchase_price*(-1)>=500;
或
WHERE sale_price>500
AND sale_price-purchase_price>=500;
*/
3.4 请写出一条 SELECT 语句,从 product 表中选取出满足“销售单价打九折之后利润高于 100 日元的办公用品和厨房用具”条件的记录。查询结果要包括 product_name 列、product_type 列以及销售单价打九折之后的利润(别名设定为 profit)。
SELECT product_name,product_type,sale_price*0.9-purchase_price AS profit
FROM product
WHERE sale_price*0.9-purchase_price>=100
AND(product_type='办公用品'
AND product_type='厨房用具');
3.5 请指出下述 SELECT 语句中所有的语法错误
SELECT product_id, SUM(product_name)
--本SELECT语句中存在错误。
FROM product
GROUP BY product_type
WHERE regist_date > ’2009-09-01’;
- 在使用聚合函数时,SELECT 子句中如果出现列名,只能是 GROUP BY 子句中指定的列名(也就是聚合键)
- 聚合函数SUM只适用于数值类型的列
- WHERE应在GROUP BY前使用,不能改为HAVING,因为HAVING只能使用GROUP BY 中指定的列名。
3.6 编写一条 SELECT 语句,求出销售单价(‘sale_price‘ 列)合计值大于进货单价(‘purchase_price‘ 列)合计值 1.5 倍的商品种类。
3.7 此前我们曾经使用 SELECT 语句选取出了 product(商品)表中的全部记录。当时我们使用了 ORDER BY子句来指定排列顺序,但现在已经无法记起当时如何指定的了。请根据下列执行结果,思考 ORDER BY 子句的内容。
首先可以判断最明显的是regist_date降序排列,其次看到同一regist_date,product_id的排序并不是系统规定的升序降序,说明还有别的排列顺序约束,对比后面的列,猜测最有可能按照sale_price或purchase_price升序排列,因此一种ORDER BY子句可能是:
ORDER BY regist_date DESC,sale_price;