选择具有多行的表中的最高出价[重复]

问题描述 投票:0回答:5

我正在使用市场的bids表,并试图获得用户的最高出价。用户可以多次出价(金额增加),因此我只希望每个列表项的最高出价。

+----+------------+---------+--------+
| 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的正确结果?

mysql sql greatest-n-per-group
5个回答
1
投票

要解决每组排名前1的问题,您要过滤器而不是集合

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

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

1
投票

您可以使用correlated子查询:

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;

1
投票

您正在运行SQL且未启用ONLY_FULL_GROUP_BY模式,这意味着MySQL只会为未分组且未聚合的列选择它喜欢的任何值。这是有效运行的内容:

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

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

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

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

如果两个用户出价相同,则每个商家信息ID将返回多行

如果您使用的是MySQL 8,则可以使用窗口函数来查找最高金额:

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"


0
投票

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

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; 

0
投票

您可以在下面尝试:

 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 
© www.soinside.com 2019 - 2024. All rights reserved.