繁体   English   中英

使用group by返回带有max()的行

[英]Using group by to return a row with max()

我正在尝试获取它们的item_id存在于数组(arr_items)中且具有较高num的项目。

player_id | item_id | num | unique_number
-----------------------------------------
10        |    1    |  1  |      1
10        |    1    |  11 |      2
10        |    1    |  93 |      3
10        |    2    |  24 |      4
10        |    2    |  40 |      5

预期的结果是获得编号为93的item_id 1,编号为40的item_id 2。

以下查询不返回任何结果。 如果删除num中的max ,它可以工作,但不会返回num最高的item_id。 假设arr_items = [1,2]

SELECT a.player_id, a.item_id, a.num, a.unique_number
FROM my_table a
    INNER JOIN
    (
        SELECT player_id, item_id, max(num) AS max_num, unique_number
        FROM my_table
        WHERE
        player_id = 10
        AND item_id IN (arr_items)
        GROUP BY item_id
    ) b ON a.item_id = b.item_id AND
           a.player_id = b.player_id AND
           a.num = b.max_num AND
           a.unique_number = b.unique_number
;

编辑:如果我从ON子句中删除unique_number ,但上面的查询工作正常,但我不太明白为什么。 我还注意到,如果我有唯一的item_id,那么它将与on子句中的unique_number字段一起使用。

这意味着如果我的桌子如下所示,它将可以正常工作。 (item_id值已更改)

player_id | item_id | num | unique_number
-----------------------------------------
10        |    0    |  1  |      1
10        |    1    |  11 |      2
10        |    2    |  93 |      3
10        |    3    |  24 |      4
10        |    4    |  40 |      5

MySQL提供了一种非标准的使用分组的方法,令人遗憾的是,“分组”已经使许多人“相信”分组就像掉日志一样简单,但是它却可以以某种方式正确地猜测/解释所需逻辑的平衡。 事实是,虽然分组很容易,但是MySQL允许的怪异的非标准语法并不总是正确的(结果是“近似值”),而且并不总是能够正确猜测。

您可以轻松地修改现有查询以实现所需的内容,但是请注意,您确实应该始终在group by子句中指定每个非聚合列。

SELECT a.player_id, a.item_id, a.num, a.unique_number
FROM my_table a
INNER JOIN (
        SELECT player_id, item_id, max(num) max_num
        FROM my_table
        GROUP BY player_id, item_id
    ) b ON a.item_id = b.item_id 
       AND a.player_id = b.player_id 
       AND a.num = b.max_num
;

将来,当MySQL确实实现窗口功能时,您将能够使用row_number()实现所需的功能,并且效率也会更高:

select * 
from (
     select *
         , row_number() over(partition by player_id, item_id
                             order by num DESC) as rn
     from my_table
     ) d
where rn = 1

nb:第二个查询始终仅对每个player_id, item_id返回一行player_id, item_id但如果对每个player_id, item_id重复num = max(num),则上面的第一个查询可能返回多个行

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM