我正在使用市场的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的正确结果?
要解决每组排名前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
您可以使用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;
您正在运行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
您可以使用以下格式并获得准确的输出:
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