ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Task03:复杂一点的查询

2020-12-19 23:33:41  阅读:275  来源: 互联网

标签:product 复杂 price sale 视图 查询 Task03 NULL


目录

3.1 本节知识整理

3.2 练习题(macOS)

3.2.1 第一部分

3.2.2 第二部分


3.1 本节知识整理

 

用法

相关说明

视图

创建视图:

CREATE VIEW <视图名称>(<列名1>,<列名2>,...) AS <SELECT语句>

修改视图结构:

ALTER VIEW <视图名> AS <SELECT语句>

更新视图内容:

  • 视图是一个虚拟表,对视图的操作就是对底层基础表的操作,所以在修改时只有满足底层基本表的定义才能成功修改

  • 当视图包含以下任意一种都不可以被更新:

聚合函数 SUM()、MIN()、MAX()、COUNT()

DISTINCT 关键字

GROUP BY 子句

HAVING 子句

UNION 或 UNION ALL 运算符

FROM 子句中包含多个表

 

 

 

 

 

 

 

 

 

 

 

 

删除视图

DROP VIEW <视图名1> [ , <视图名2> …]

 

  • 视图是基于真实表的一张虚拟的表,其数据来源均建立在真实表的基础上

  • 视图只包含使用时动态检索数据的查询

  • 视图vs表:是否保存了实际的数据

YnTlq5vR65wRlPdk

  • 为什么使用视图:

    • 重用SQL语句

    • 简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道它的基本查询细节

    • 使用表的组成部分而不是整个表

    • 保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限

    • 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据

  • PS:在一般的DBMS中定义视图时不能使用ORDER BY语句;因为为视图和表一样,数据行都是没有顺序的

 

 子查询

 

一个查询语句嵌套在另一个查询语句内部的查询

嵌套子查询

与在视图上再定义视图类似,子查询也没有具体的限制

应尽量避免嵌套多层子查询

标量子查询

执行的SQL语句只能返回一个值,也就是要返回表中具体的某一行的某一列

能够使用常数或者列名的地方,无论是 SELECT 子句、GROUP BY 子句、HAVING 子句,还是 ORDER BY 子句,几乎所有的地方都可以使用

先执行内层查询,再执行外层查询

关联子查询

查询与子查询之间存在着联系

先执行外层查询,再执行内层查询

 

关联子查询执行过程详解:

https://zhuanlan.zhihu.com/p/41844742

函数

算术函数 (用来进行数值计算的函数):

函数

说明

+ - * /

加减乘除四则运算

ABS(数值)

绝对值

MOD(被除数,除数)

求余数,小数没有余数的概念,只能对整数列求余数

ROUND(对象数值,保留小数的位数)

四舍五入,当参数保留小数的位数为变量时,可能会遇到错误,请谨慎使用变量

 

 

 

 

 

 

 

 

 

 

 

 

 

字符串函数 (用来进行字符串操作的函数):

函数

说明

CONCAT(str1,str2,...)

字符串拼接

LENGTH(str)

字符串长度

UPPER(str)/LOWER(str)

大小写转换

REPLACE(str,from_str,to_str)

将字符串str中from_str替换为to_str

SUBSTR(str,pos,len)

截取字符串str中pos位置开始,长度为len的字符串

截取的起始位置从字符串最左侧开始计算,索引值起始为1

SUBSTRING_INDEX(str,delim,count)

获取原始字符串按照分隔符分割后,第 count 个分隔符delim之前(或之后)的子字符串,支持正向和反向索引,索引起始值分别为 1 和 -1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

日期函数 (用来进行日期操作的函数):

函数

说明

CURRENT_DATE

当前日期

CURRENT_TIME 

当前时间

CURRENT_TIMESTAMP

当前日期和时间

EXTRACT(unit FROM date)

截取出日期数据中的一部分

unit: YEAR/MONTH/DAY/HOUR/MINUTE/SECOND

 

 

 

 

 

 

 

 

 

 

 

 

转换函数 (用来转换数据类型和值的函数):

函数

说明

CAST(expr AS type)

将expr转换为type类型

COALESCE(数据1, 数据2,数据3...)

返回从左侧开始第 1个不是NULL的值

 

 

 

 

 

 

 

聚合函数 (用来进行数据聚合的函数):参考Task02: 基础排序与查询笔记

NA

谓词

谓词就是返回值为真值的函数,包括TRUE/FALSE/UNKNOWN

谓词

说明

LIKE

字符串的部分一致查询

前方一致、中间一致和后方一致,%代表“零个或多个任意字符串”的特殊符号,_(下划线)代表“任意1个字符”

BETWEEN

范围查询,[]闭区间

IS NULL/IS NOT NULL

判断是否为NULL

为了选取出某些值为 NULL 的列的数据,不能使用 =,而只能使用特定的谓词IS NULL

IN

OR的简便用法,多个查询条件取并集时可以选择使用OR语句

需要注意的是,在使用IN 和 NOT IN 时是无法选取出NULL数据的

EXIST

判断是否存在满足某种条件的记录,如果存在这样的记录就返回真(TRUE),如果不存在就返回假(FALSE)

 

 

CASE表达式

CASE WHEN <求值表达式> THEN <表达式>
     WHEN <求值表达式> THEN <表达式>
     WHEN <求值表达式> THEN <表达式>
     .
     .
     .
ELSE <表达式>
END  

依次判断WHEN表达式是否为真值,是则执行THEN后的语句,如果所有的WHEN表达式均为假,则执行ELSE后的语句

  • 应用场景1:根据不同分支得到不同列值

  • 应用场景2:实现列方向上的聚合

  • (扩展内容)应用场景3:实现行转列

  • 当待转换列为数字时,可以使用SUM/AVG/MAX/MIN等聚合函数

  • 当待转换列为文本时,可以使用MAX/MIN等聚合函数

3.2 练习题(macOS)

3.2.1 第一部分

1. 创建出满足下述三个条件的视图(视图名称为 ViewPractice5_1)。使用 product(商品)表作为参照表,假设表中包含初始状态的 8 行数据。

  • 条件 1:销售单价大于等于 1000 日元。

  • 条件 2:登记日期是 2009 年 9 月 20 日。

  • 条件 3:包含商品名称、销售单价和登记日期三列。

对该视图执行 SELECT 语句的结果如下所示。

SELECT * FROM ViewPractice5_1;

执行结果

product_name | sale_price | regist_date
--------------+------------+------------
T恤衫         |   1000    | 2009-09-20
菜刀          |    3000    | 2009-09-20

只要写出对应的SELECT语句,再添加创建视图的语句即可:

CREATE VIEW ViewPractice5_1 (product_name, sale_price, regist_date) AS
SELECT product_name, sale_price, regist_date
FROM product
WHERE sale_price >= 1000
AND regist_date = '2009-09-20';

2. 向习题1中创建的视图 ViewPractice5_1 中插入如下数据,会得到什么样的结果呢?

INSERT INTO ViewPractice5_1 VALUES (' 刀子 ', 300, '2009-11-02');

说明:会报错。视图是一个虚拟表,对视图的操作就是对底层基础表的操作,所以在修改时只有满足底层基本表的定义才能成功修改;上述插入语句只包含了视图ViewPractice5_1所选出来的列名,并未包含地处基础表product的所有列名,特别是primary key不能为NULL。

3. 请根据如下结果编写 SELECT 语句,其中 sale_price_all 列为全部商品的平均销售单价。

product_id | product_name | product_type | sale_price | sale_price_all
------------+-------------+--------------+------------+---------------------
0001       | T恤衫         | 衣服         | 1000       | 2097.5000000000000000
0002       | 打孔器        | 办公用品      | 500        | 2097.5000000000000000
0003       | 运动T恤       | 衣服          | 4000      | 2097.5000000000000000
0004       | 菜刀          | 厨房用具      | 3000       | 2097.5000000000000000
0005       | 高压锅        | 厨房用具      | 6800       | 2097.5000000000000000
0006       | 叉子          | 厨房用具      | 500        | 2097.5000000000000000
0007       | 擦菜板        | 厨房用具       | 880       | 2097.5000000000000000
0008       | 圆珠笔        | 办公用品       | 100       | 2097.5000000000000000

利用标量子查询即可实现上述结果:

SELECT product_id,
       product_name,
       sale_price,
       (SELECT AVG(sale_price) 
		FROM product) AS sale_price_all
FROM product;

4. 请根据习题一中的条件编写一条 SQL 语句,创建一幅包含如下数据的视图(名称为AvgPriceByType)。

product_id | product_name | product_type | sale_price | avg_sale_price
------------+-------------+--------------+------------+---------------------
0001       | T恤衫         | 衣服         | 1000       |2500.0000000000000000
0002       | 打孔器         | 办公用品     | 500        | 300.0000000000000000
0003       | 运动T恤        | 衣服        | 4000        |2500.0000000000000000
0004       | 菜刀          | 厨房用具      | 3000        |2795.0000000000000000
0005       | 高压锅         | 厨房用具     | 6800        |2795.0000000000000000
0006       | 叉子          | 厨房用具      | 500         |2795.0000000000000000
0007       | 擦菜板         | 厨房用具     | 880         |2795.0000000000000000
0008       | 圆珠笔         | 办公用品     | 100         | 300.0000000000000000

提示:其中的关键是 avg_sale_price 列。与习题3不同,这里需要计算出的是各商品种类的平均销售单价。这与使用关联子查询所得到的结果相同。 也就是说,该列可以使用关联子查询进行创建。问题就是应该在什么地方使用这个关联子查询。

利用关联子查询,将外层查询的product_type传递到内层查询中计算分类产品的平均销售单价,并返回作为新建列avg_sale_price的值:

CREATE VIEW AvgPriceByType AS
SELECT product_id, product_name, product_type, sale_price,
	   (SELECT AVG(sale_price)
		FROM product AS p1
		WHERE p1.product_type = p2.product_type
		GROUP BY product_type) AS avg_sale_price
FROM product AS p2;

 

3.2.2 第二部分

1. 运算或者函数中含有 NULL 时,结果全都会变为NULL ?(判断题)

正确☑️

说明:

SELECT ABS(NULL), MAX(NULL), SUM(NULL);

结果:

+-----------+----------------------+-----------+
| ABS(NULL) | MAX(NULL)            | SUM(NULL) |
+-----------+----------------------+-----------+
|      NULL | 0x                   |      NULL |
+-----------+----------------------+-----------+
1 row in set (0.00 sec)

2. 对本章中使用的 product(商品)表执行如下 2 条 SELECT 语句,能够得到什么样的结果呢?

注:product表建表过程请参考Task02: 基础排序与查询-2.2.1练习题第一部分准备工作

SELECT product_name, purchase_price
FROM product
WHERE purchase_price NOT IN (500, 2800, 5000);

结果:返回purchase_price不为500,2800,5000的producet_name,purchase_price,且不包含purchase_price为空的行

+--------------+----------------+
| product_name | purchase_price |
+--------------+----------------+
| 打孔器       |            320 |
| 擦菜板       |            790 |
+--------------+----------------+
2 rows in set (0.00 sec)

SELECT product_name, purchase_price
FROM product
WHERE purchase_price NOT IN (500, 2800, 5000, NULL);

结果:返回为空,结合上一题运算或函数中含有NULL,结果都会变为NULL;如果要筛选NULL对应行,一定要用IS NULL或者IS NOT NULL

Empty set (0.00 sec)

3. 按照销售单价( sale_price)对练习 6.1 中的 product(商品)表中的商品进行如下分类。

  • 低档商品:销售单价在1000日元以下(T恤衫、办公用品、叉子、擦菜板、 圆珠笔)

  • 中档商品:销售单价在1001日元以上3000日元以下(菜刀)

  • 高档商品:销售单价在3001日元以上(运动T恤、高压锅)

请编写出统计上述商品种类中所包含的商品数量的 SELECT 语句,结果如下所示。

low_price | mid_price | high_price
----------+-----------+------------
        5 |         1 |         2

观察结果,分别统计了不同分类标准下所包含的商品数量,利用聚合函数+CASE WHEN表达式实现:

SELECT SUM(CASE WHEN sale_price <= 1000 THEN 1 ELSE 0 END) AS low_price,
	   SUM(CASE WHEN sale_price > 1000 AND sale_price <= 3000 THEN 1 ELSE 0 END) AS mid_price,
	   SUM(CASE WHEN sale_price > 3000 THEN 1 ELSE 0 END) AS high_price
FROM product;

 

 

 

标签:product,复杂,price,sale,视图,查询,Task03,NULL
来源: https://blog.csdn.net/weixin_47171389/article/details/111322151

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有