Select 最高出价 table 多行

Select highest bid in table with multiple rows

我正在为一个市场与 bids table 合作,并试图获得用户的最高出价。一个用户可以多次出价(金额增加),因此我只想要每个列表项目的最高出价。

+----+------------+---------+--------+
| id | listing_id | user_id | amount |
+----+------------+---------+--------+
|  1 |          1 |       1 |      5 |
|  2 |          2 |       1 |     10 |
|  3 |          2 |       1 |     15 |
+----+------------+---------+--------+

我希望最终结果是:

+----+------------+---------+--------+
| id | listing_id | user_id | amount |
+----+------------+---------+--------+
|  1 |          1 |       1 |      5 |
|  3 |          2 |       1 |     15 |
+----+------------+---------+--------+

我试过以下查询:

select bids.id, bids.listing_id, bids.user_id, max(bids.amount) as amount 
from bids 
group by listing_id;

但这给了我以下(对我来说)奇怪的结果:

+----+------------+---------+--------+
| id | listing_id | user_id | amount |
+----+------------+---------+--------+
|  1 |          1 |       1 |      5 |
|  2 |          2 |       1 |     15 |
+----+------------+---------+--------+

金额15是正确的,但ID=2来自金额=10的记录。 如何获得记录 id=1 和 id=3 的正确结果?

要解决这个每组前 1 名的问题,您需要 filter 而不是 aggregate

这是使用相关子查询的一种方法:

select b.*
from bids b
where b.amount = (
    select max(b1.amount) 
    from bids 
    where b1.listing_id = b.listing_id and b1.user_id = b.user_id
)

另一种典型的解决方案是使用反left join:

select b.*
from bids b
left join bids b1 
    on b1.listing_id = b.listing_id and b1.user_id = b.user_id and b1.amount > b.amount
where b1.id is null

您可以使用相关子查询:

select b.*
from bids b
where b.amount = (select max(b1.amount) from bids b1 where b1.listing_id = b.listing_id );

其他选项是使用排名功能:

select b.*
from (select b.*, rank() over (partition by b.listing_id order by b.amount desc) as seq
      from bids b
     ) b
where seq = 1;

你运行在没有打开 ONLY_FULL_GROUP_BY 模式的情况下使用你的 SQL,这意味着 MySQL 将只为未打开的列选择它喜欢的任何值分组而不聚合。这实际上是 运行:

select ANY(bids.id), bids.listing_id, ANY(bids.user_id), max(bids.amount) as amount
from bids group by listing_id

ANY 不是真正的聚合函数,但可以想象它是,它只是 return 来自组的随机结果。这就是您的数据变得混乱的方式

您可以 运行 组作为子查询并将组加入回 table 以获取其余数据,如下所示:

select * from
(
  select listing_id, max(bids.amount) as amount
  from bids 
  group by listing_id
) findmax
inner join 
bids b
on 
  b.listing_id = findmax.listing_id and 
  b.amount = findmax.maxamount

如果两个用户出价相同,这将 return 每个列表 ID 多行

如果您在 MySQL 8,您可以使用 window 函数来查找最高金额:

select * from
(
  select 
    bids.id, bids.listing_id, bids.user_id, bids.amount as amount,
    row_number() over(partition by bids.listing_id order by amount desc) as rown
  from bids group by listing_id, bids.id, bids.user_id
) x
where x.rown = 1

我推荐你enable "only full group by"

您可以使用以下格式并获得准确的输出:

select  B.id, B.listing_id, B.user_id, id, A.max_amount
from bids B
left outer join (
  select listing_id, user_id, max(amount) as max_amount from bids group by listing_id, user_id
) as A on A.listing_id = B.listing_id and A.user_id = B.user_id
order by B.listing_id, B.user_id, B.id; 

你可以试试下面这个:

 select b.id,b.listing_id,b.user_id,b1.amount from bids b inner join (select listing_id,max(amount) as amount from bids group by listing_id) b1
    on b.amount=b1.amount