mysql 排序Top-P-From-Top-Q查询的SQL汇总输出

ddarikpa  于 2023-03-17  发布在  Mysql
关注(0)|答案(1)|浏览(106)

给定SQL RollUp查询的输出如下:

SELECT
        COALESCE(name, "Total"),
        COALESCE(event, "Total"),
        SUM(raised) AS money
    FROM money_raised
    GROUP BY name, event WITH ROLLUP
+--------+--------+-----------+
| name   | event  | money     |
+--------+--------+-----------+
| 2      | Total  | 9         |
| 1      | a      | 2         |
| 2      | b      | 3         |
| 1      | c      | 4         |
| Total  | Total  | 16        |
| 1      | Total  | 7         |
| 2      | a      | 4         |
| 1      | b      | 1         |
| 2      | c      | 2         |
+--------+--------+-----------+

我如何扩展查询(或者重新实现它,如果你认为有更好的方法),以排序的结果,以获得前p个事件的总金额筹集前q个人的总金额降序,例如,q = 2和p = 2,我想要下面的输出.

+--------+--------+-----------+
| name   | event  | money     |
+--------+--------+-----------+
| 2      | a      | 4         |
| 2      | b      | 3         |
| 1      | c      | 4         |
| 1      | a      | 2         |
+--------+--------+-----------+

个人“2”列在第一位,因为他们总共筹集了9个,然后我们列出了他们的前两个事件,“a”筹集了4个,“B”筹集了3个。然后列出个人“1”,因为他们只筹集了7个,并且有前两个事件“c”和“a”。
谢谢!
我在想下面的一些事情,但不确定如何将每一条记录与其相应的个人筹集的“总”资金联系起来。

SELECT * FROM (
    SELECT
        COALESCE(name, "Total"),
        COALESCE(event, "Total"),
        SUM(raised) AS money
    FROM money_raised
    GROUP BY name, event WITH ROLLUP
) 
ORDER BY [...]

原始数据看起来如下所示(假设我正确地把数字加起来):

date,   name,   event,      money
1       2       b           1
2       2       b           2
1       1       a           1
3       1       a           1
1       1       c           3
4       2       a           2
3       1       c           1
3       2       a           1
2       1       b           1
6       2       a           1
5       2       c           2
deyfvvtc

deyfvvtc1#

我知道你想要前2个人的前2个事件。这建议窗口函数,计算每个人的总金额,然后对事件和个人进行排名。
这里有一种方法:

select name, event, money
from (
    select m.*,
        dense_rank() over(order by money_for_name desc) rn1,
        dense_rank() over(partition by name order by money desc) rn2
    from (
        select name, event, 
            sum(raised) as money,
            sum(sum(raised)) over(partition by name) money_for_name
        from money_raised
        group by name, event
    ) m
) m
where rn1 <= 2 and rn2 <= 2
order by rn1, rn2

最内部的子查询按事件和名称进行聚合,还计算每个名称的小计(money_for_name);下一个级别按总金额(rn1)对个人进行排名,并对每个个人的事件进行排名(rn2)。最后一步只是对排名进行过滤并对结果进行排序。
我不确定您是否以及如何希望在此处的图片中进行汇总。

相关问题