有人可以帮我弄清楚我的查询有误吗?

时间:2020-09-21 20:25:58

标签: sql sum window-functions

我正在尝试创建一个查询,该查询返回数据库中所有钱最多的人的一半以下的人的名字。 这些是我的查询:

  select P1.name 
    from Persons P1 left join 
         AccountOf A1 on A1.person_id = P1.id left join 
         BankAccounts B1 on B1.id = A1.account_id
group by name
  having SUM(B1.balance) < MAX((select SUM(B1.balance) as b
                                  from AccountOf A1 left join 
                                       BankAccounts B1 on B1.id = A1.account_id
                              group by A1.person_id 
                              order by b desc 
                                 LIMIT 1)) * 0.5

这是结果:

+-------+
| name  |
+-------+
| Evert |
+-------+

数据库中有以下表格:

+---------+--------+--+
| Persons |        |  |
+---------+--------+--+
| id      | name   |  |
| 11      | Evert  |  |
| 12      | Xavi   |  |
| 13      | Ludwig |  |
| 14      | Ziggy  |  |
+---------+--------+--+
+--------------+---------+
| BankAccounts |         |
+--------------+---------+
| id           | balance |
| 11           | 525000  |
| 12           | 750000  |
| 13           | 1900000 |
| 14           | 1600000 |
+--------------+---------+
+-----------+-----------+------------+
| AccountOf |           |            |
+-----------+-----------+------------+
| id        | person_id | account_id |
| 301       | 11        | 12         |
| 302       | 13        | 12         |
| 303       | 13        | 14         |
| 304       | 14        | 11         |
| 305       | 14        | 13         |
+-----------+-----------+------------+

我在这里想念什么?我应该在结果中得到两个条目(Evert,Xavi)

2 个答案:

答案 0 :(得分:0)

我不会以这种方式处理逻辑(我将使用窗口函数)。但是您最终的having具有两个聚合级别。那不行您想要:

having SUM(B1.balance) < (select 0.5 * SUM(B1.balance) as b
                          from AccountOf A1 join
                               BankAccounts B1 on B1.id = A1.account_id
                          group by A1.person_id
                          order by b desc 
                          limit 1
                         )

我还将0.5移到了子查询中,并将left join更改为join -这些表需要进行匹配才能获得余额。

答案 1 :(得分:0)

如果您的-未公开,我会推荐窗口功能! -数据库支持它们。

您只能加入和聚合一次,然后使用窗口max()获得最高余额。然后剩下的就是过滤外部查询:

select *
fom (
    select p.id, p.name, coalesce(sum(balance), 0) balance,
        max(sum(balance)) over() max_balance 
    from persons p
    left join accountof ao on ao.person_id = p.id
    left join bankaccounts ba on ba.id = ao.account_id
    group by p.id, p.name
) t
where balance > max_balance * 0.5