MySQL 获取列的最大值并回退到第二列
MySQL getting maximum of column with fallback to second column
+------+---------+--------+---------+---------+---------+
| 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 | ... |
+------+---------+--------+---------+---------+---------+
我有一个 table 与上面的相似。 id
、user_id
和 obj_id
是外键; created
和 applied
是存储为整数的时间戳。我需要获取整行,按 user_id
和 obj_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;
并在代码中解决问题,但是这个 table 变得相当大,我想要一个 SQL 解决方案来获取我需要的数据。
感谢 Mark Heintz 的评论,this answer 让我到达了我需要去的地方。
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;
去阅读答案以了解其工作原理的详细信息; left join
尝试为同一用户和对象查找最近应用的行。如果没有,它会查找同时应用但最近创建的行。
以上意味着任何没有更新的行来替换它的行都将具有 next_max_applied.applied 空值。这些行由 IS NULL
子句过滤。
最后,group by
子句处理任何具有相同用户、对象、应用和创建列的行。
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 return 具有 user_id, obj_id, max(applied), max(created)
的(不同的)行。将这些与 in 子句一起使用,子查询 B 检索单个 ID 的列表,每个 ID 都与具有 user_id、obj_id、max(applied)、max(created) 的适当值相关联。所以你有一组有效的 id 来获取你的结果。
主要 select 使用这些 ID select 您需要的结果。
+------+---------+--------+---------+---------+---------+
| 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 | ... |
+------+---------+--------+---------+---------+---------+
我有一个 table 与上面的相似。 id
、user_id
和 obj_id
是外键; created
和 applied
是存储为整数的时间戳。我需要获取整行,按 user_id
和 obj_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;
并在代码中解决问题,但是这个 table 变得相当大,我想要一个 SQL 解决方案来获取我需要的数据。
感谢 Mark Heintz 的评论,this answer 让我到达了我需要去的地方。
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;
去阅读答案以了解其工作原理的详细信息; left join
尝试为同一用户和对象查找最近应用的行。如果没有,它会查找同时应用但最近创建的行。
以上意味着任何没有更新的行来替换它的行都将具有 next_max_applied.applied 空值。这些行由 IS NULL
子句过滤。
最后,group by
子句处理任何具有相同用户、对象、应用和创建列的行。
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 return 具有 user_id, obj_id, max(applied), max(created)
的(不同的)行。将这些与 in 子句一起使用,子查询 B 检索单个 ID 的列表,每个 ID 都与具有 user_id、obj_id、max(applied)、max(created) 的适当值相关联。所以你有一组有效的 id 来获取你的结果。
主要 select 使用这些 ID select 您需要的结果。