【问题标题】:SQL get id of max bill per waiterSQL获取每个服务员最大账单的ID
【发布时间】:2016-01-01 01:33:18
【问题描述】:

我使用的是 PostgreSQL 数据库,并且有两个类似的表

服务员id、姓名)

账单id、金额、id_waiter

我正在寻找每个服务员最大金额的账单 ID。

我找到了以下解决方案

SELECT waiter.id AS waiter, maxamount, bills.id AS bill
FROM waiter
JOIN (
  SELECT id_waiter, max(amount) AS maxamount
  FROM bills
  GROUP BY id_waiter) AS maxis ON maxis.id_waiter = waiter.id
JOIN bills ON maxis.maxamount = bills.amount AND waiter.id =     bills.id_kellner

它有效,但它似乎有点多余,我想知道是否有更好的方法来做到这一点。我不喜欢的是 bills 被连接了两次,一次在子查询中,一次在末尾。

这是一些示例数据

样本数据

服务员餐桌

id | name
1 | john
2 | joe

账单表

id | amount | id_waiter
1 | 20 | 1
2 | 25 | 2
3 | 50 | 2
4 | 20 | 1
5 | 60 | 1
6 | 10 | 2

结果如下所示

waiter | maxamount | bill
1 | 60 | 5
2 | 50 | 3

【问题讨论】:

  • 样本数据会很好...

标签: postgresql max greatest-n-per-group


【解决方案1】:

在 Postgres 中你可以使用DISTINCT ON:

select distinct on(id_waiter) id_waiter, amount max_amount, id bill
from bills
order by 1, 2 desc;

 id_waiter | max_amount | bill 
-----------+------------+------
         1 |         60 |    5
         2 |         50 |    3
(2 rows)    

事实上join如果你想选择服务员的名字也是必要的:

select id_waiter, name, max_amount, bill
from (
    select distinct on(id_waiter) id_waiter, amount max_amount, id bill
    from bills
    order by 1, 2 desc
    ) sub
join waiters w on w.id = id_waiter;

 id_waiter | name | max_amount | bill 
-----------+------+------------+------
         1 | john |         60 |    5
         2 | joe  |         50 |    3
(2 rows)    

SqlFiddle

【讨论】:

  • 谢谢@klin,这很好用。如果我做对了,使用distinct on,您将选择由 id_waiter 和 max_amount 排序的每个组中的第一个。我想知道性能。我的例子是对一些更复杂和更大的数据集的抽象。我相信排序比找到最大值要贵一点,对吧?如果我没记错的话,应该可以在 O(n) 中找到最大值,排序下限为 O(n log n)。两者都可以通过在数量列上维护索引树结构来减少。我的数据库背景不太深,抱歉。
  • 你是对的,在非索引列上 max() 稍微快一些。在我的服务器上,大约 500 毫秒到 600 毫秒,而 max() 支持 500 万个整数。在索引列上,差异应该太小而不会被注意到。
猜你喜欢
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-11
  • 2021-11-12
  • 2021-01-10
  • 1970-01-01
相关资源
最近更新 更多