在mysql中,sum(a)和sum(a) over()有啥区别?
Posted
技术标签:
【中文标题】在mysql中,sum(a)和sum(a) over()有啥区别?【英文标题】:In mysql, What is the difference between sum(a) and sum(a) over()?在mysql中,sum(a)和sum(a) over()有什么区别? 【发布时间】:2021-01-13 21:49:22 【问题描述】:我认为它们都用于将所有数字相加。但是我的代码只能通过使用 sum(a) over() 才能被接受。
select avg(1.0*Number) median
from (
select *, sum(Frequency) over(order by Number) pos,
(sum(Frequency) over())/2.0 mid
from Numbers
) A
where mid between pos-Frequency and pos
【问题讨论】:
【参考方案1】:从this document我们可以了解到:
SQL SUM 函数用于返回 SELECT 语句中表达式的总和。
总和在多行中返回一个值,因此我们应该清楚是否要将标量放在所有这些行或一行中。如果我们想把它放在所有这些行中,我们可以使用window functions
(partition),否则我们可以使用group by
(aggregation)。
我们创建一个表如下:
架构 (MySQL v8.0)
CREATE TABLE orders (
`trade_date` DATETIME,
`ticker` VARCHAR(4),
`trans_type` VARCHAR(4),
`quantity` INTEGER
);
INSERT INTO orders
(`trade_date`, `ticker`, `trans_type`, `quantity`)
VALUES
('2020-12-10', 'FB', 'BUY', '100'),
('2020-12-28', 'FB', 'BUY', '50'),
('2020-12-29', 'FB', 'SELL', '80'),
('2020-12-30', 'FB', 'SELL', '30'),
('2020-12-31', 'FB', 'BUY', '40'),
('2020-11-16', 'AAPL', 'BUY', '30'),
('2020-11-17', 'AAPL', 'SELL', '70'),
('2020-11-20', 'AAPL', 'BUY', '50'),
('2020-11-24', 'AAPL', 'BUY', '40');
让我们先使用group by
。
查询 #1
SELECT
ticker, SUM(CASE WHEN trans_type='SELL' THEN -quantity ELSE quantity END) AS net_quantity
FROM
orders
group by ticker;
ticker | net_quantity |
---|---|
FB | 80 |
AAPL | 50 |
View on DB Fiddle
我们可以看到,对于每个股票代码,总和被折叠成一个值,我们不能在 select
子句中添加其他字段。
我们来看看分区方法:
查询 #2
SELECT
trade_date,
ticker,
trans_type,
quantity,
SUM(CASE WHEN trans_type='SELL' THEN -quantity ELSE quantity END) OVER (partition by ticker) AS net_quantity
FROM
orders;
trade_date | ticker | trans_type | quantity | net_quantity |
---|---|---|---|---|
2020-11-16 00:00:00 | AAPL | BUY | 30 | 50 |
2020-11-17 00:00:00 | AAPL | SELL | 70 | 50 |
2020-11-20 00:00:00 | AAPL | BUY | 50 | 50 |
2020-11-24 00:00:00 | AAPL | BUY | 40 | 50 |
2020-12-10 00:00:00 | FB | BUY | 100 | 80 |
2020-12-28 00:00:00 | FB | BUY | 50 | 80 |
2020-12-29 00:00:00 | FB | SELL | 80 | 80 |
2020-12-30 00:00:00 | FB | SELL | 30 | 80 |
2020-12-31 00:00:00 | FB | BUY | 40 | 80 |
View on DB Fiddle
所有两个总和都附加到每一行。可以参考this answer。
【讨论】:
以上是关于在mysql中,sum(a)和sum(a) over()有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB相当于MySQL:select count(*) c, sum(if(x='A',1,0)) as a, sum(if(x='B',1,0)) as b
MySql 左连接几个表后怎么进行统计?count(*)、sum(..)