select coalesce(SP.shop_id, '不确定') as shop_id, P.product_id
from Shopproduct SP
right outer join Product P
on SP.product_id = P.product_id;
26) 窗口函数:<窗口函数> over ([partition by <列清单>] order by <排序用列清单>),partition by 在横向上对表进行分组(不是必须的),order by 决定了纵向排序规则,窗口函数只能写在select语句中,能够作为窗口函数的聚合函数:sum、avg、count、max、min,专用窗口函数:rank、dense_rank、row_number,可以不使用partition by
select product_id, product_name, sale_price, sum(sale_price) over(order by product_id) as current_sum
from Product;
或
select product_id, product_name, sale_price, avg(sale_price) over (order by product_id rows between 1 preceding and 1 following) as moving_avg
from Product;
29) group by rollup(product_type)可以一次计算两种组合的汇总结果,其中合计行记录称为超级分组记录,默认使用null作为聚合键,如果要插入插入字符串,使用grouping函数:
select case when grouping(product_type) = 1 then '商品种类 合计' else product_type end as product_type, case when grouping(regist_date) = 1 then '登记日期 合计' else cast(regist_date as varchat(16)) end as regist_date, sum(sale_price) as sum_price
select case when grouping(product_type) = 1 then '商品种类 合计' else product_type end as product_type, case when grouping(regist_date) = 1 then '登记日期 合计' else cast(regist_date as varchat(16)) end as regist_date, sum(sale_price) as sum_price
from Product
group by grouping sets(product_type, regist_date);
之前我们说过,在 SELECT 语句中视图可以和表一样使用。那么, 对于 INSERT、 DELETE、 UPDATE 这类更新语句(更新数据的 SQL) 来说,会怎么样呢? 实际上,虽然这其中有很严格的限制,但是某些时候也可以对视图进 行更新。标准 SQL 中有这样的规定:如果定义视图的 SELECT 语句能够 满足某些条件,那么这个视图就可以被更新。下面就给大家列举一些比较 具有代表性的条件。 ① SELECT 子句中未使用 DISTINCT ② FROM 子句中只...
2017-12-16 16:58:05
之前我们说过,在 SELECT 语句中视图可以和表一样使用。那么,
对于 INSERT、 DELETE、 UPDATE 这类更新语句(更新数据的 SQL)
来说,会怎么样呢?
实际上,虽然这其中有很严格的限制,但是某些时候也可以对视图进
行更新。标准 SQL 中有这样的规定:如果定义视图的 SELECT 语句能够
满足某些条件,那么这个视图就可以被更新。下面就给大家列举一些比较
具有代表性的条件。
① SELECT 子句中未使用 DISTINCT
② FROM 子句中只有一张表
③ 未使用 GROUP BY 子句
④ 未使用 HAVING 子句
使用GROUP BY子句可以像切蛋糕那样将表分割。通过使用聚合函数和 GROUP BY子句,可以根据“商品种类”或者“登记日期”等将表分割后再 进行汇总。 ● 聚合键中包含NULL时,在结果中会以“不确定”行(空行)的形式表现出来。 ● 使用聚合函数和GROUP BY子句时需要注意以下4点。 ① 只能写在SELECT子句之中 ② GROUP BY子句中不能使用SELECT子句中列的别名 ③ GROUP BY子句的聚合结果是无序的 ④ WHERE子句中不能使用聚合函数
2017-12-16 16:11:47
使用GROUP BY子句可以像切蛋糕那样将表分割。通过使用聚合函数和
GROUP BY子句,可以根据“商品种类”或者“登记日期”等将表分割后再
进行汇总。
● 聚合键中包含NULL时,在结果中会以“不确定”行(空行)的形式表现出来。
● 使用聚合函数和GROUP BY子句时需要注意以下4点。
① 只能写在SELECT子句之中
② GROUP BY子句中不能使用SELECT子句中列的别名
③ GROUP BY子句的聚合结果是无序的
④ WHERE子句中不能使用聚合函数
虽然条件分别写在 WHERE 子句和 HAVING 子句当中,但是条件的 内容以及返回的结果都完全相同。因此,大家可能会觉得两种书写方式都 没问题。 如果仅从结果来看的话,确实如此。但笔者却认为,聚合键所对应的 条件还是应该书写在 WHERE 子句之中。 理由有两个。 首先,根本原因是 WHERE 子句和 HAVING 子句的作用不同。如前 所述, HAVING 子句是用来指定“组”的条件的。因此,“行”所对应的 条件还是应该写在 WHERE 子句当中...
2017-12-16 16:24:28
虽然条件分别写在 WHERE 子句和 HAVING 子句当中,但是条件的
内容以及返回的结果都完全相同。因此,大家可能会觉得两种书写方式都
没问题。
如果仅从结果来看的话,确实如此。但笔者却认为,聚合键所对应的
条件还是应该书写在 WHERE 子句之中。
理由有两个。
首先,根本原因是 WHERE 子句和 HAVING 子句的作用不同。如前
所述, HAVING 子句是用来指定“组”的条件的。因此,“行”所对应的
条件还是应该写在 WHERE 子句当中。这样一来,书写出的 SELECT 语
句不但可以分清两者各自的功能,理解起来也更加容易。
WHERE 子句 = 指定行所对应的条件
HAVING 子句 = 指定组所对应的条件
其次,对初学者来说,研究 DBMS 的内部实现这一话题有些深奥,
这里就不做介绍了,感兴趣的读者可以参考随后的专栏——WHERE 子句
和 HAVING 子句的执行速度。
WHERE子句和HAVING子句的执行速度
在 WHERE 子句和 HAVING 子句中都可以使用的条件,最好写在 WHERE 子
句中的另一个理由与性能即执行速度有关系。由于性能不在本书介绍的范围之内,
因此暂不进行说明。通常情况下,为了得到相同的结果,将条件写在 WHERE 子句
中要比写在 HAVING 子句中的处理速度更快,返回结果所需的时间更短。
为了理解其中原因,就要从 DBMS 的内部运行机制来考虑。使用 COUNT 函
数等对表中的数据进行聚合操作时,DBMS 内部就会进行排序处理。排序处理是
会大大增加机器负担的高负荷的处理 A。因此,只有尽可能减少排序的行数,才能
提高处理速度。
通过 WHERE 子句指定条件时,由于排序之前就对数据进行了过滤,因此能够
减少排序的数据量。但 HAVING 子句是在排序之后才对数据进行分组的,因此与
在 WHERE 子句中指定条件比起来,需要排序的数据量就会多得多。虽然 DBMS
的内部处理不尽相同,但是对于排序处理来说,基本上都是一样的。
此外, WHERE 子句更具速度优势的另一个理由是,可以对 WHERE 子句指定条
件所对应的列创建索引,这样也可以大幅提高处理速度。创建索引是一种非常普遍
的提高 DBMS 性能的方法,效果也十分明显,这对 WHERE 子句来说也十分有利。
select coalesce(SP.shop_id, '不确定') as shop_id, P.product_id
from Shopproduct SP
right outer join Product P
on SP.product_id = P.product_id;
26) 窗口函数:<窗口函数> over ([partition by <列清单>] order by <排序用列清单>),partition by 在横向上对表进行分组(不是必须的),order by 决定了纵向排序规则,窗口函数只能写在select语句中,能够作为窗口函数的聚合函数:sum、avg、count、max、min,专用窗口函数:rank、dense_rank、row_number,可以不使用partition by
select product_id, product_name, sale_price, sum(sale_price) over(order by product_id) as current_sum
from Product;
或
select product_id, product_name, sale_price, avg(sale_price) over (order by product_id rows between 1 preceding and 1 following) as moving_avg
from Product;
29) group by rollup(product_type)可以一次计算两种组合的汇总结果,其中合计行记录称为超级分组记录,默认使用null作为聚合键,如果要插入插入字符串,使用grouping函数:
select case when grouping(product_type) = 1 then '商品种类 合计' else product_type end as product_type, case when grouping(regist_date) = 1 then '登记日期 合计' else cast(regist_date as varchat(16)) end as regist_date, sum(sale_price) as sum_price
select case when grouping(product_type) = 1 then '商品种类 合计' else product_type end as product_type, case when grouping(regist_date) = 1 then '登记日期 合计' else cast(regist_date as varchat(16)) end as regist_date, sum(sale_price) as sum_price
from Product
group by grouping sets(product_type, regist_date);
之前我们说过,在 SELECT 语句中视图可以和表一样使用。那么, 对于 INSERT、 DELETE、 UPDATE 这类更新语句(更新数据的 SQL) 来说,会怎么样呢? 实际上,虽然这其中有很严格的限制,但是某些时候也可以对视图进 行更新。标准 SQL 中有这样的规定:如果定义视图的 SELECT 语句能够 满足某些条件,那么这个视图就可以被更新。下面就给大家列举一些比较 具有代表性的条件。 ① SELECT 子句中未使用 DISTINCT ② FROM 子句中只...
2017-12-16 16:58:05
之前我们说过,在 SELECT 语句中视图可以和表一样使用。那么,
对于 INSERT、 DELETE、 UPDATE 这类更新语句(更新数据的 SQL)
来说,会怎么样呢?
实际上,虽然这其中有很严格的限制,但是某些时候也可以对视图进
行更新。标准 SQL 中有这样的规定:如果定义视图的 SELECT 语句能够
满足某些条件,那么这个视图就可以被更新。下面就给大家列举一些比较
具有代表性的条件。
① SELECT 子句中未使用 DISTINCT
② FROM 子句中只有一张表
③ 未使用 GROUP BY 子句
④ 未使用 HAVING 子句
0 有用 靖哥哥 2016-10-21 11:15:54
简单易读,条理清晰,看完能读懂别人的程序了。解决一大难题。
0 有用 透 2018-11-26 13:22:24
写得细致,口语话,确实也算啰嗦。
0 有用 michaelcxb 2021-11-21 20:58:47
很适合初学者
0 有用 rainbow树袋 2016-02-01 00:13:23
这本书是日本MICK所写,非常适合初学者。论述的角度是读者的角度,会换位思考到读者在看到这一段时候会发出怎样的疑问,非常难得;原始数据的例题只有一道,但是可以反复从不同角度提出不同的问题进行处理,避免了眼花缭乱之感;习题也比较有趣,有的问题反而是属于问题本身其实是个陷阱的,考验初学者。
0 有用 蔗蔗蔗大王 2021-12-17 22:02:05
最好的SQL书!
0 有用 巡回飞行员 2022-05-05 01:25:32
sql入门最佳教程
0 有用 小咖喱黄不辣 2021-12-29 21:37:03
基础但不枯燥,很好的入门之作。
0 有用 蔗蔗蔗大王 2021-12-17 22:02:05
最好的SQL书!
0 有用 michaelcxb 2021-11-21 20:58:47
很适合初学者
0 有用 草莓大福 2021-10-22 14:27:44
最好的SQL入门教程没有之一,逻辑清晰,细致但不啰嗦