在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 如何让sum函数保留小数位

MySql 左连接几个表后怎么进行统计?count(*)、sum(..)

mysql if

mysql SQL语句如何将sum()放在where后面做条件怎么写呢?

MySQL聚合函数