繁体   English   中英

SQL:聚合超过聚合(最大超过总和)

[英]SQL: aggregate over aggregate (max over sums)

我在创建有效查询以聚合聚合子查询时遇到问题。 MySQL 允许一些非 ANSI 构造,但它们给出不正确的结果。

CREATE TABLE `log` (
  `id` int NOT NULL,
  `id_user` varchar(32) NOT NULL,
  `datastamp` datetime NOT NULL DEFAULT now(),
  `processed` int NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`));

我希望有一个由每年的“最佳”用户组成的结果表(其中“最佳”意味着在处理的字段中具有最高的总和),例如:

源表:

2010 | u1 | 1
2010 | u1 | 3
2010 | u2 | 2
2011 | u1 | 1
2011 | u1 | 1
2011 | u2 | 5

结果:

2010 | u1 | 4
2011 | u2 | 5

简单查询

select year(datastamp) as y, id_user, sum(processed) as ps from log group by id_user, y

给出每个用户和年份的所有总和:

2010 | u1 | 4
2010 | u2 | 2
2011 | u1 | 2
2011 | u2 | 5

但我不能 select 行每年的总和最高。 尝试类似的东西

select y, max(ps), id_user from(...) group by y

尽管被 MySQL 接受,但给出了不正确的 id_user 字段。 我在 stackoverflow 上找到的其他解决方案建议使用子查询加入基表,但我不能在 ON 条件内使用聚合结果(sum(processed) as ps)。

我认为在这种情况下,窗口函数可能会对您有所帮助。 您可以使用以下查询查询数据 -

select *
from
(

select year, id_user, ps, rank() over (partition by year order by ps desc) as ranks_per_year
from
(
select year, id_user, sum(processed) as ps
from table
group by 1,2
) A 

) B
where ranks_per_year = 1

rank()dense_rank()是在出现平局时可以使用的 2 种方法。

在此处输入图像描述

如果rank()像您提到的那样在您的引擎中不起作用,您可以在 go 前面使用max() function。 这是查询

with tbl as 
(
select '2010' as year,'u1' as id_user,1 as processed union all
select '2010','u1',3 union all
select '2010','u2',2 union all
select '2011','u1',1 union all
select '2011','u1',1 union all
select '2011','u2',5 
)

select *
from
(

select year, id_user, ps, 
max(ps) over (partition by year) as max_ps_per_year 
from
(
select year, id_user, sum(processed) as ps
from tbl
group by 1,2
) A 

) B
where ps = max_ps_per_year

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM