股票资本损益:卖出记正、买入记负
LeetCode 1393 · 带符号求和、条件聚合
面试怎么回答
按股票分组,SUM(CASE WHEN operation = 'Sell' THEN price ELSE -price END),卖出记正、买入记负,求和就是损益。能一次聚合解决的就不要先开窗再分组。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
股票操作表记录每支股票每天的买入或卖出操作和价格,每次卖出前都有对应的买入。求每支股票的总损益(所有卖出价之和减去所有买入价之和)。
表结构
- Stocks:stock_name、operation(Buy / Sell)、operation_day、price;(stock_name, operation_day) 为主键
思路
损益就是卖出总额减去买入总额,一次分组就够:卖出记正价、买入记负价,求和即可。原解法用两个窗口 SUM 再分组去重,结果对但绕了一圈。
参考解法
select stock_name,sell-buy capital_gain_loss
from(
select stock_name ,
sum(if(operation='Buy', price,0))over(partition by stock_name ) buy,
sum(if(operation='Sell',price,0))over(partition by stock_name) sell
from Stocks s
)t1
group by stock_name,buy,sell
另一种写法:一次分组的带符号求和
SELECT stock_name, SUM(IF(operation = 'Sell', price, -price)) AS capital_gain_loss
FROM Stocks
GROUP BY stock_name
易错点
- 窗口函数 + GROUP BY 去重是多余的,直接 GROUP BY 一次条件求和就行。