ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

天池龙珠计划SQL_Task03

2021-04-07 15:58:27  阅读:179  来源: 互联网

标签:product 龙珠 price 视图 查询 SQL Task03 type SELECT


Task03:复杂查询方法

本笔记为阿里云天池龙珠计划SQL训练营的学习内容,链接为:https://tianchi.aliyun.com/specials/promotion/aicampsql;

3.1 视图

3.1.1 视图与表

视图是一个虚拟的表,不同于直接操作数据表,视图是依据SELECT语句来创建的,所以操作视图时会根据创建视图的SELECT语句生成一张虚拟表,然后在这张虚拟表上做SQL操作。
可以看作是一个窗口,通过这个窗口我们可以看到数据库表中真实存在的数据
在这里插入图片描述

3.1.2 为什么会存在视图

  • 通过定义视图可以将频繁使用的SELECT语句保存以提高效率。
  • 通过定义视图可以使用户看到的数据更加清晰。
  • 通过定义视图可以不对外公开数据表全部字段,增强数据的保密性。
  • 通过定义视图可以降低数据的冗余。

3.1.3 如何创建视图

CREATE VIEW <视图名称>(<列名1>,<列名2>,...) AS <SELECT语句>
CREATE VIEW view_shop_product(product_type, sale_price, shop_name)
AS
SELECT product_type, sale_price, shop_name
  FROM product,
       shop_product
 WHERE product.product_id = shop_product.product_id;
注意事项

是在一般的DBMS中定义视图时不能使用ORDER BY语句。

3.1.4 修改视图结构:

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

3.1.5 更新视图内容

对于一个视图来说,如果包含以下结构的任意一种都是不可以被更新的:

聚合函数 SUM()、MIN()、MAX()、COUNT() 等。
DISTINCT 关键字。
GROUP BY 子句。
HAVING 子句。
UNION 或 UNION ALL 运算符。
FROM 子句中包含多个表。

UPDATE productsum
   SET sale_price = '5000'
 WHERE product_type = '办公用品';
  • 原表也可以发现数据也被更新
  • 视图只是原表的一个窗口,所以它修改也只能修改透过窗口能看到的内容
  • 并不推荐这种使用方式, 而且我们在创建视图时也尽量使用限制不允许通过视图来修改表

3.1.6 删除视图:

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

3.2 子查询

SELECT stu_name
FROM (
         SELECT stu_name, COUNT(*) AS stu_cnt
          FROM students_info
          GROUP BY stu_age) AS studentSum;

3.2.1 子查询

子查询指一个查询语句嵌套在另一个查询语句内部的查询
(子查询就是 SQL内部生成的表)

3.2.2 子查询和视图的关系

子查询就是将用来定义视图的 SELECT 语句直接用于 FROM 子句当中。其中AS studentSum可以看作是子查询的名称,而且由于子查询是一次性的,所以子查询不会像视图那样保存在存储介质中, 而是在 SELECT 语句执行之后就消失了。

3.2.3 标量子查询

标量就是单一的意思,那么标量子查询也就是单一的子查询:就是要求我们执行的SQL语句只能返回一个值,也就是要返回表中具体的某一行的某一列。

3.2.4 标量子查询的作用

必须而且只能返回1行1列的结果,因此标量子查询的返回值可以用在=或者<>这样需要单一值的比较运算符之中。

eg. 查询出销售单价高于平均销售单价的商品

SELECT product_id, product_name, sale_price
  FROM product
 WHERE sale_price > (SELECT AVG(sale_price) FROM product);

标量子查询:SELECT AVG(sale_price) FROM product

3.2.5 关联子查询

就是通过一些标志将内外两层的查询连接起来起到过滤数据的目的
eg. 选取出各商品种类中高于该商品种类的平均销售单价的商品

SELECT product_type, product_name, sale_price
  FROM product ASp1
 WHERE sale_price > (SELECT AVG(sale_price)
   FROM product AS p2
                      WHERE p1.product_type =p2.product_type
   GROUP BY product_type);
关联查询的执行过程:
  • 首先执行不带WHERE的主查询
  • 根据主查询讯结果匹配product_type,获取子查询结果
  • 将子查询结果再与主查询结合执行完整的SQL语句

3.3 函数

函数大致分为如下几类:
算术函数 (用来进行数值计算的函数)
字符串函数 (用来进行字符串操作的函数)
日期函数 (用来进行日期操作的函数)
转换函数 (用来转换数据类型和值的函数)
聚合函数 (用来进行数据聚合的函数)

3.3.1 算数函数

  • ABS – 绝对值 语法:ABS( 数值 )
  • MOD – 求余数 语法:MOD( 被除数,除数 )
  • ROUND – 四舍五入 语法:ROUND( 对象数值,保留小数的位数 )

3.3.2 字符串函数

  • CONCAT – 拼接 语法:CONCAT(str1, str2, str3)
  • LENGTH – 字符串长度 语法:LENGTH( 字符串 )
  • LOWER – 小写转换 LOWER 函数只能针对英文字母使用,它会将参数中的字符串全都转换为小写
  • REPLACE – 字符串的替换 语法:REPLACE( 对象字符串,替换前的字符串,替换后的字符串 )
  • SUBSTRING – 字符串的截取 语法:SUBSTRING (对象字符串 FROM 截取的起始位置 FOR 截取的字符数)
    使用 SUBSTRING 函数 可以截取出字符串中的一部分字符串。截取的起始位置从字符串最左侧开始计算,索引值起始为1。

3.3.3 日期函数

  • CURRENT_DATE – 获取当前日期
  • CURRENT_TIME – 当前时间
  • CURRENT_TIMESTAMP – 当前日期和时间
  • EXTRACT – 截取日期元素
    语法:EXTRACT(日期元素 FROM 日期)
    使用 EXTRACT 函数可以截取出日期数据中的一部分
SELECT CURRENT_TIMESTAMP as now,
EXTRACT(YEAR   FROM CURRENT_TIMESTAMP) AS year,
EXTRACT(MONTH  FROM CURRENT_TIMESTAMP) AS month,
EXTRACT(DAY    FROM CURRENT_TIMESTAMP) AS day,
EXTRACT(HOUR   FROM CURRENT_TIMESTAMP) AS hour,
EXTRACT(MINUTE FROM CURRENT_TIMESTAMP) AS MINute,
EXTRACT(SECOND FROM CURRENT_TIMESTAMP) AS second;
+---------------------+------+-------+------+------+--------+--------+
| now                 | year | month | day  | hour | MINute | second |
+---------------------+------+-------+------+------+--------+--------+
| 2020-08-08 17:34:38 | 2020 |     8 |    8 |   17 |     34 |     38 |
+---------------------+------+-------+------+------+--------+--------+

3.3.4 转换函数

在 SQL 中主要有两层意思:一是数据类型的转换,简称为类型转换,在英语中称为cast;另一层意思是值的转换。

CAST – 类型转换

语法:CAST(转换前的值 AS 想要转换的数据类型)

-- 将字符串类型转换为数值类型
SELECT CAST('0001' AS SIGNED INTEGER) AS int_col; 
-- 将字符串类型转换为日期类型
SELECT CAST('2009-12-14' AS DATE) AS date_col;       

COALESCE – 将NULL转换为其他值

语法:COALESCE(数据1,数据2,数据3……)
该函数会返回可变参数 A 中左侧开始第 1个不是NULL的值。参数个数是可变的,因此可以根据需要无限增加。

SELECT COALESCE(NULL, 11) AS col_1,
COALESCE(NULL, 'hello world', NULL) AS col_2,
COALESCE(NULL, NULL, '2020-11-01') AS col_3;
+-------+-------------+------------+
| col_1 | col_2       | col_3      |
+-------+-------------+------------+
|    11 | hello world | 2020-11-01 |
+-------+-------------+------------+      

3.4 谓词

谓词就是返回值为真值的函数。
包括TRUE / FALSE / UNKNOWN。
谓词主要有以下几个:
LIKE
BETWEEN
IS NULL、IS NOT NULL
IN
EXISTS

= 只能判断普通数值。
is 只能判断null值
<=> 安全等于都可以

3.4.1(not)like:通配搜索

一般与通配符搭配使用,对字符型数据进行部分匹配查询
常见的通配符:_任意单个字符 %任意多个字符

Eg. 特殊情况使用转移字符
即设置$符号为转移字符(其他符号也可以)

-查询员工姓名中第二个字符为_的员工信息
SELECT*
FROM `employees`
WHERE `last_name` LIKE '_$_%' ESCAPE '$'

3.4.2 (not) in

功能:查询某字段的值是否属于指定范围内

-查询部门编号为30/50/90的员工的员工名,部门编号
SELECT`last_name`,`department_id`
WHERE `department_id`IN(30,50,90)
FROM `employees`

3.4.3 between …and…

如果不想让结果中包含临界值,那就必须使用 < 和 >

-查询年薪不是100000-20000之间的员工姓名,工资,年薪
SELECT`last_name`,`salary`,`salary`*12*(1+IFNULL(`commission_pct`,0))  '年 薪'
FROM `employees`
WHERE `salary`*12*(1+IFNULL(`commission_pct`,0)) NOT BETWEEN 100000 AND 200000;

3.4.4 is (not) null

-查询奖金率为0的员工信息
SELECT *
FROM `employees`
WHERE `commission_pct` IS NULL

3.4.5 使用子查询作为IN谓词的参数

SELECT product_name, sale_price
FROM product
WHERE product_id IN (SELECT product_id
  FROM shopproduct
                       WHERE shop_id = '000C');

展开后的结果

SELECT product_name, sale_price
FROM product
WHERE product_id IN ('0003', '0004', '0006', '0007');

你会疑惑既然 in 谓词也能实现,那为什么还要使用子查询呢,因为使用子查询即可保持 sql 语句不变,极大提高了程序的可维护性,这是系统开发中需要重点考虑的内容。

3.4.6 EXIST (*)

  • 谓词的作用就是 “判断是否存在满足某种条件的记录”。
  • 如果存在这样的记录就返回真(TRUE),如果不存在就返回假(FALSE)。
  • EXIST的主语是“记录”。
  • EXIST的参数:只需要在右侧书写 1 个参数,通常都会是一个子查询。
  • 子查询中的SELECT *:由于 EXIST 只关心记录是否存在,因此返回哪些列都没有关系。 EXIST 只会判断是否存在满足子查询中 WHERE 子句指定的条件
  • 使用NOT EXIST替换NOT IN

3.5 CASE 表达式

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

SELECT  product_name,
        CASE WHEN product_type = '衣服'    THEN CONCAT('A : ',product_type)
             WHEN product_type = '办公用品' THEN CONCAT('B : ',product_type)
             WHEN product_type = '厨房用具' THEN CONCAT('C : ',product_type)
             ELSE NULL
        END AS abc_product_type
  FROM  product;

语法:

case
when 条件1 then 要显示的值1或语句1;
when 条件2 then 要显示的值2或语句2;
...
else 要显示的值n或语句n;
end 新名称--新名称可以省略

ELSE 子句也可以省略不写,这时会被默认为 ELSE NULL(最好还是写)。
此外,最后的“END”是不能省略的

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

SELECT product_type,
       SUM(sale_price) AS sum_price
  FROM product
 GROUP BY product_type;  
+--------------+-----------+
| product_type | sum_price |
+--------------+-----------+
| 衣服         |      5000 |
| 办公用品      |       600 |
| 厨房用具      |     11180 |
+--------------+-----------+

假如要在列的方向上展示不同种类额聚合值,该如何写呢?

sum_price_clothes | sum_price_kitchen | sum_price_office
------------------+-------------------+-----------------
             5000 |             11180 |              600  

聚合函数 + CASE WHEN 表达式即可实现该效果

-- 对按照商品种类计算出的销售单价合计值进行行列转换
SELECT SUM(CASE WHEN product_type = '衣服' THEN sale_price ELSE 0 END) AS sum_price_clothes,
       SUM(CASE WHEN product_type = '厨房用具' THEN sale_price ELSE 0 END) AS sum_price_kitchen,
       SUM(CASE WHEN product_type = '办公用品' THEN sale_price ELSE 0 END) AS sum_price_office
  FROM product;
+-------------------+-------------------+------------------+
| sum_price_clothes | sum_price_kitchen | sum_price_office |
+-------------------+-------------------+------------------+
|              5000 |             11180 |              600 |
+-------------------+-------------------+------------------+

应用场景3:实现行转列

标签:product,龙珠,price,视图,查询,SQL,Task03,type,SELECT
来源: https://blog.csdn.net/xiaobaizsj/article/details/115482958

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

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

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

ICode9版权所有