MySQL通过回退到第二列获得最大列

时间:2016-07-29 18:21:13

标签: mysql greatest-n-per-group

+------+---------+--------+---------+---------+---------+
| id   | user_id | obj_id | created | applied | content |
+------+---------+--------+---------+---------+---------+
|    1 |       1 |      1 |       1 |       1 | ...     |
|    2 |       1 |      2 |       1 |       1 | ...     |
|    3 |       1 |      1 |       1 |       2 | ...     |
|    4 |       1 |      2 |       2 |       2 | ...     |
|    5 |       2 |      1 |       1 |       1 | ...     |
|    6 |       2 |      2 |       1 |       1 | ...     |
+------+---------+--------+---------+---------+---------+

我有一张类似上面的表格。 iduser_idobj_id是外键; createdapplied是以整数形式存储的时间戳。我需要获得整个行,按user_idobj_id分组,最大值为applied。如果两行具有相同的applied值,我需要支持created的最大值。所以对于上面的数据,我想要的输出是:

+------+---------+--------+---------+---------+---------+
| id   | user_id | obj_id | created | applied | content |
+------+---------+--------+---------+---------+---------+
|    1 |       1 |      1 |       1 |       1 | ...     |
|    4 |       1 |      2 |       2 |       2 | ...     |
|    5 |       2 |      1 |       1 |       1 | ...     |
|    6 |       2 |      2 |       1 |       1 | ...     |
+------+---------+--------+---------+---------+---------+

我目前的解决方案是按applied然后created

订购所有订单
select * from data order by applied desc created desc;

并在代码中进行排序,但是这个表变得非常大,我想要一个只获取所需数据的SQL解决方案。

2 个答案:

答案 0 :(得分:0)

感谢Mark Heintz的评论,this answer让我到达了我需要的地方。

    for i in range(1000,100,-1):
        for j in range(1000,100,-1):
            product=j*k

请阅读答案,详细了解其工作原理; SELECT data.id, data.user_id, data.obj_id, data.created, data.applied, data.content FROM data LEFT JOIN data next_max_applied ON next_max_applied.user_id = data.user_id AND next_max_applied.obj_id = data.obj_id AND ( next_max_applied.applied > data.applied OR ( next_max_applied.applied = data.applied AND next_max_applied.created > data.created ) ) WHERE next_max_applied.applied IS NULL GROUP BY user_id, obj_id; 尝试为同一用户和对象查找最近应用的行。如果没有,它会同时发现一行,但最近才创建。

以上意味着没有更新的行来替换它的任何行都将具有next_max_applied.applied值null。这些行由left join子句过滤。

最后,IS NULL子句处理具有相同用户,对象,应用和创建列的所有行。

答案 1 :(得分:0)

select * 
from my_table
where id in (
  /* inner subquery b */
  select max(id) 
      from my_table where 
      (user_id, obj_id, applied, created) in (
          /* inner subquery A */
          select user_id, obj_id, max(applied), max(created) 
          from my_table 
          group by user_id, obj_id
      )
);

然后内部子查询A返回具有user_id, obj_id, max(applied), max(created)的(不同)行。在子句中使用这些子查询B可以检索单个ID的列表,每个ID都使用适当的user_id,obj_id,max(应用),max(已创建)值进行重新排列。所以你有一个有效的id集合来获得你的结果。

主选择使用这些ID选择您需要的结果。