GroupBy 用法的三重境界,面试终结者

点击蓝色“有关SQL”关注我哟

加个“星标”,天天与8000人一起快乐成长

图 | 榖依米

知乎上,有人说 SQL 很简单,24 小时就能入门;也有人说,数据库很简单,7周7数据库。

看着这些言论,我一度怀疑自己是不是又虚度了几年光阴。

接着翻翻,这些言论家洋洋洒洒罗列一堆的 SQL 语法,翻来覆去就是 SELECT *, 再一看,哦,原来作者是 XX 培训机构老师。一口老血封住我少见了世面的喉咙司令官。

为了显摆自己 SQL 知识的丰富,我经常在面试中加入 GroupBy 基础语法的考察,当然这类题并不会影响给候选者发 Offer. 那什么会影响呢,下回我们好好讲,这次只讲技术细节。

GroupBy,熟悉 SQL 的朋友都知道,是对集合数据做分组聚合运算。

举个最简单的例子,大概就长这样:

SELECT OrderMonth,City,Sum(OrderAmount) AS OrderAmount
FROM dbo.FctSalesMonthly 
GROUP BY OrderMonth ,City

用意很简单,统计每个月,每个城市的销售额。如果面试的时候,面试官给了你一道这样的题,说明面试的岗位相对初级一些,只要对维度有概念,这样的题,应该不能错。

接下来,我可能会为难你一下,除了统计每月每城市的销售额外,还要求统计每个月的总销售额,每个城市的总销售,以及总销售额,并且(这是古怪的需求)用一条 SQL 语句完成,结果集只能用一个

请注意最后一个要求,只能用一条SQL语句完成,结果集还只能有一个!

这时,解法可能就多了。有同学用动态SQL,有同学用CTE(不知道的同学谷歌里百度一下),有同学用子查询。很可能写了 n 多行的SQL。但事实上,只要在GroupBy上添加一行:

SELECT OrderMonth,City,Sum(OrderAmount) AS OrderAmount
FROM dbo.FctSalesMonthly 
GROUP BY 
    Cube(OrderMonth,City) 
ORDER BY OrderMonth DESC,City

这样的题,其实对候选人也只是经验层面的考量。如果你碰巧对 SQL 特别感兴趣,又碰巧读过文档,那你肯定知道。但如果你不知道,也只能说明你还年轻。

如果上面两题都没难住你,那么我就会往第三个方向问了:

下面两段 SQL,同样求每月订单的最大销售额,哪个最优?

SELECT OrderMonth,Max(OrderAmount) AS MaxAmount 
FROM FctSalesMonthly
GROUP BY OrderMonth
ORDER BY OrderMonth
SELECT Sales.OrderMonth,RSL.Amount AS MaxAmount 
FROM FctSalesMonthly Sales 
CROSS APPLY(SELECT TOP 1 Amt.OrderAmount
            FROM FctSalesMonthly Amt 
            WHERE Amt.OrderMonth = Sales.OrderMonth
            )RSL 
ORDER BY Sales.OrderMonth 

我们都知道第二条SQL肯定不是最佳,同表扫描多次,性能就会很次。即使表数据完全缓存起来,排序依然耗CPU. 但第一条好在哪里?这就是重点,体现SQL的功底和经验的地方。

比如,你需要会看执行计划,需要熟知中间可能会发生的聚合, Hash Match, Stream Aggregate 以及其性能和适用条件。

Stream Aggregate 在全表或全索引扫描一遍的情况下,便可实现分组,配合索引能极快的加速排序。而Hash Match则是在混乱的分组场景下,得到快速分组。

如果上述例子中,OrderMonth 上并没有索引,你猜,执行计划会选择 Hash Match 还是 Stream Aggregate ? 

--完--

往期精彩:

本号精华合集(二)

如何写好 5000 行的 SQL 代码

如何提高阅读 SQL 源代码的快感

我在面试数据库工程师候选人时,常问的一些题

零基础 SQL 数据库小白,从入门到精通的学习路线与书单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dbLenis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值