DataWhale组队学习:SQL-TASK03

1、对视图的理解
《sql基础教程**第2版》用一句话非常凝练的概括了视图与表的区别—“是否保存了实际的数据”。所以视图并不是数据库真实存储的数据表,它可以看作是一个窗口,通过这个窗口我们可以看到数据库表中真实存在的数据。所以我们要区别视图和数据表的本质,即视图是基于真实表的一张虚拟的表,其数据来源均建立在真实表的基础上。

那既然已经有数据表了,为什么还需要视图呢?主要有以下几点原因:

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

视图不仅可以基于真实表,我们也可以在视图的基础上继续创建视图。

虽然在视图上继续创建视图的语法没有错误,但是我们还是应该尽量避免这种操作。这是因为对多数 DBMS 来说, 多重视图会降低 SQL 的性能。

2、视图的更改会直接改原始表的数据,因为视图本身是原始表的一个窗口而已。

3、学会利用标量子查询:
标量子查询的意思是返回一个值。例如

select avg(product_name) from product

标量子查询的使用场景:

查询出销售单价高于平均销售单价的商品
select product_id, product_name, sale_price
  from product
 where sale_price > (select avg(sale_price) from product)

由于标量子查询的特性,导致标量子查询不仅仅局限于 WHERE 子句中,通常任何可以使用单一值的位置都可以使用。也就是说, 能够使用常数或者列名的地方,无论是 SELECT 子句、GROUP BY 子句、HAVING 子句,还是 ORDER BY 子句,几乎所有的地方都可以使用。

4、关于关联子查询,这个知识点必须要真的理解才知道怎么操作的,这个博客写的很好https://zhuanlan.zhihu.com/p/41844742,我自己的理解是,它主要是类似一个FOR循环,先执行的是主查询,之后看关联语句,把关联语句的第一个值传入子查询,对子查询进行执行,并返回相应的结果到主查询;把关联语句的第二个值传入子查询,对子查询进行执行,并返回相应的结果到主查询;以此类推,进行for循环。

选取出各商品种类中高于该商品种类的平均销售单价的商品。

SELECT product_type, product_name, sale_price
  FROM product AS p1
 WHERE sale_price > (SELECT AVG(sale_price)
                       FROM product AS p2
                      WHERE p1.product_type = p2.product_type
                      GROUP BY product_type);

但是,我以往的做法都是join两个表,之后再一个嵌套select出来。也不是不可以,但是感觉没有像上面那个语法简单。

练习:
NO1


image.png
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';

NO2:


image.png

看下执行结果:


image.png

原因是:造成该问题的原因是: 当向视图中插入数据时,同时也会向原表插入数据插入数据 ,而原表中存在多个字段不允许为空,所以无法插入。
image.png

我们把NOT NULL的字段填上

create or replace View ViewPractice5_2(product_name, sale_price, regist_date, product_id, product_type)
 as
select product_name, sale_price, regist_date,product_id, product_type
from product
where sale_price >= 1000 and regist_date = '2009-09-20';

insert into ViewPractice5_2 values (' 刀子 ', 300, '2009-11-02',100, '办公用品');
select * from ViewPractice5_2;
image.png

image.png

结果是insert 成功了,但是视图却没有改变,WHY?
答案是对视图的操作其实是对原始表的操作Insert是到原始表了,但是由于我们视图创建时有一个条件是where sale_price >= 1000 and regist_date = '2009-09-20';所以,在view里是看不到新插入的数据的,在原始表里才能看到!!

看看原始表的情况:


image.png

NICE! 和预计的一样!

NO3


image.png

这里先有个小tips,由于我做了上一题,插入了一行数据,我先要用delete from table where product_id = 100删除这一行,结果出现了这个情况:


image.png

一番搜索之后发现原来是MySQL Workbench的安全设置。当要执行的SQL语句是进行批量更新或者删除的时候就会提示这个错误。
解决方法是:
image.png

改完之后需要重启一下,才能生效。


image.png

好嘞,下面开始做这个题:
考点是【对标量子查询的理解】
select product_id, product_name, 
product_type, sale_price, 
(select avg(sale_price) from product) as sale_price_all
from product
image.png

NO4:


image.png

这个考察的是关联子查询,我的方法是,先写子查询的逻辑,然后搞清楚它返回的是什么,返回的就是一个标量,之后需要嵌入主查询做FOR循环!!

select product_id, product_name, product_type, sale_price , (SELECT AVG(sale_price)
 FROM product as table2
 where table2.product_type = table1.product_type
 group by product_type) as avg_sale_price
 from product as table1

运行结果如下:


image.png

函数介绍
这里只挑了一些我不太常用的,一般忘记了就现用现查。
1、算术函数
ROUND( 对象数值,保留小数的位数 ) ----四舍五入
2、字符串函数
SUBSTRING(对象字符串 FROM 截取的起始位置 FOR 截取的字符数)---- 字符串的截取,sql中下标从1开始
例子:从product_name第3个字符开始,往后取2个

select product_name,substring(product_name from 3 for 2) as sub_string
from product;
image.png

substring_index(原始字符串, 分隔符,n) :以分隔符split,取第n个分割之前的内容,起始索引为1,倒序起始索引为-1
类似于python中的split()函数

SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);

结果是www.mysql

获取第N个元素,需要嵌套N次,取-1
例如:获取 'www.mysql.com' 中的 mysql

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('www.mysql.com', '.', 2), '.' , -1);

3、日期函数
---获取当前时间

select current_timestamp;

---获取当前日期

select current_date;

---获取当前时刻

select current_time;

截取日期元素 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;

4、转换函数
COALESCE – 将NULL转换为其他值
CAST(转换前的值 AS 想要转换的数据类型)

谓词
谓词:返回值为真值的函数

image.png

1、LIKE
---用‘%’正则,前方一致、中间一致和后方一致
--前方:dddaa匹配

SELECT *
FROM samplelike
WHERE strcol LIKE 'ddd%';

--中间:abcdddcsv匹配

SELECT *
FROM samplelike
WHERE strcol LIKE '%ddd%';

--后方:aaasvddd匹配

SELECT *
FROM samplelike
WHERE strcol LIKE '%ddd';

---用‘_’正则任意1个字符
aadddcsv匹配

SELECT *
FROM samplelike
WHERE strcol LIKE '__ddd___';

2、between :闭区间,[],
where column between 100 and 1000

3、IN
where column IN (123,345,578,12346)

4、善于用“子查询”代替 IN 和 NOT IN
使用子查询即可保持 sql 语句不变,极大提高了程序的可维护性,这是系统开发中需要重点考虑的内容。实际生活中,某个门店的在售商品是不断变化的,使用 in 谓词就需要经常更新 sql 语句,降低了效率,提高了维护成本;实际上,某个门店的在售商品可能有成百上千个,手工维护在售商品编号真是个大工程。

-- NOT IN 使用子查询作为参数,取出未在大阪门店销售的商品的销售单价
SELECT product_name, sale_price
  FROM product
 WHERE product_id NOT IN (SELECT product_id
                            FROM shopproduct
                           WHERE shop_id = '000A');

5、exist & not exist: 是否存在符合条件的记录,这个应该是个非常好用的谓词!!!因为你可以把【限定条件】全都放到【关联子查询】中,同时不必要想子查询需要筛选出来什么,直接子查询select * 或者select 1就好!!!!!

SELECT product_name, sale_price
  FROM product AS p
 WHERE EXISTS (SELECT 1 -- 这里可以书写适当的常数
                 FROM shopproduct AS sp
                WHERE sp.shop_id = '000C'
                  AND sp.product_id = p.product_id);
SELECT product_name, sale_price
  FROM product AS p
 WHERE NOT EXISTS (SELECT *
                     FROM shopproduct AS sp
                    WHERE sp.shop_id = '000A'
                      AND sp.product_id = p.product_id);

6.CASE
注意END不可省略!!!


image.png

image.png
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;

7、聚合函数+CASE WHEN ... THEN... ELSE...END 在业务中是经常用到的!!
核心思想是:先想你最终需要的表的列是哪几个,然后再插入计算的东西。(要什么拿什么)


image.png

第一步构建框架:

select name,
          ......chinese,
          ......math,
          ......english
from
    table1
group by name;

第二步,填充内容:

select name,
          sum(case when subject = '语文' then score else 0 end) as chinese,
          sum(case when subject = '数学' then score else 0 end) math,
          sum(case when subject = '英语' then score else 0 end) english
from
    table1
group by name;

搞定~~~

哦~终于到了第二部分的练习了!!LET'S DO IT!!

NO.1:


image.png

NO.2:


image.png

结果:


image.png

image.png

带上了null以后,所有的结果都没有了,这是因为,谓词是对真值的判断,Null没有对应的真值,它是unknown

NO.3:


image.png
 SELECT   
    sum(case when sale_price <= 1000 then 1 else 0 end) as low_price,
    sum(case when sale_price > 1001 and sale_price < 3001 then 1 else 0 end) as low_price,
    sum(case when sale_price > 3001 then 1 else 0 end)  as high_price
  from product
image.png

NICE~

好嘞,今天的打卡就到这里了~
完成和坚持是第一步,所以今天又走了一步呢~我想你也和我一样

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容

  • 2017/3/14 RDBMS:关系型数据库管理系统 关系模型独立于语言 SQL有几种不同类型的语言:数据定义语言...
    ancherl阅读 1,608评论 0 6
  • 1、select 用法(略)2、where 用法(略)3、关于*和DISTINCT 4、COUNT(*)会得到包含...
    emmmmeee阅读 313评论 0 0
  • 5复杂查询 5-1视图 视图和表 当我们创建表时,会通过INSERT语句将数据保存到数据库中,而数据库中的数据会被...
    los_pollos阅读 517评论 0 0
  • 第一次亲密接触 一、数据库相关概念: ①、数据库的好处: 1、持久化数据到本地2、使用数据库管理软件进行结构化查询...
    凉风有信2020阅读 278评论 0 0
  • 题目汇总 day9:文件与文件系统【08月08日 23:59】 文件与文件系统 【打开文件】open(file, ...
    dataTONG阅读 491评论 0 0