MySQL 排序的分组依据 table
MySQL Group By for sorted table
我有两个具有这些结构的表:
Table 1(评论)
+----+---------+------------+--------+---------+
| id | post_id | created_at | author | content |
+----+---------+------------+--------+---------+
| 1 | 3 | 03-01-2020 | Jack | XXX |
| 2 | 1 | 02-29-2020 | Joe | XXX |
| 3 | 3 | 02-24-2020 | Anna | XXX |
| 4 | 2 | 03-01-2020 | Mia | XXX |
+----+---------+------------+--------+---------+
Table 2 (posts)
+-----+-------------+---------------------+---------+
| id | category_id | name | content |
+-----+-------------+---------------------+---------+
| 1 | 1 | some random name | xxxxxxx |
| 2 | 2 | another random name | xxxxxxx |
| 3 | 1 | third random name | xxxxxxx |
+-----+-------------+---------------------+---------+
我的目标是获得一个列表,其中包含来自特定 category_id
的每个 post 的最新评论。
因此,例如,如果我将类别 1 作为输入,我需要 ID 为 2 和 1 的评论,因为这些始终是给定类别的每个 post 的最后评论。
到目前为止,我得到了这个查询,其中 returns 所有条目都按创建日期排序。
select *
from comments c
join posts p on c.post_id = p.id
where p.category_id = 1
order by c.created_at desc;
我已经阅读了有关 group by
属性 的信息,但这并不能保证我能获得最后的条目。我该如何解决这个问题?
假设 Table2
是 类别 table,如果您只想在结果中包含 Table1
的列,那么您不需要不需要加入。
使用 NOT EXISTS
:
select t1.*
from table_1 t1
where not exists (
select 1 from table_1
where table2_id = t1.table2_id and created_at > t1.created_at
)
或相关子查询:
select t1.*
from table_1 t1
where t1.created_at = (select max(created_at) from table_1 where table2_id = t1.table2_id)
编辑:
select c.*
from posts p inner join (
select c.* from comments c
where not exists (
select 1 from comments
where post_id = c.post_id and created_at > c.created_at
)
) c on c.post_id = p.id
where p.category_id = ?
参见demo。
或者:
select c.*
from posts p inner join (
select c.* from comments c
where c.post_id in (select id from posts where category_id = ?)
and not exists (
select 1 from comments
where post_id = c.post_id and created_at > c.created_at
)
) c on c.post_id = p.id
参见demo。
将 ?
替换为您要搜索的 category_id
。
结果:
| id | post_id | created_at | author | content |
| --- | ------- | ------------------- | ------ | ------- |
| 1 | 3 | 2020-03-01 00:00:00 | Jack | XXX |
| 2 | 1 | 2020-02-29 00:00:00 | Joe | XXX |
将 GROUP BY
与聚合函数 MAX
结合使用应该可以解决您的问题:
SELECT
b.id AS category_id,
MAX(a.created_at) AS last_created
FROM table_1 a
JOIN table_2 b on a.table2_id = b.id
GROUP BY b.id
ORDER BY last_created DESC;
我有两个具有这些结构的表:
Table 1(评论)
+----+---------+------------+--------+---------+
| id | post_id | created_at | author | content |
+----+---------+------------+--------+---------+
| 1 | 3 | 03-01-2020 | Jack | XXX |
| 2 | 1 | 02-29-2020 | Joe | XXX |
| 3 | 3 | 02-24-2020 | Anna | XXX |
| 4 | 2 | 03-01-2020 | Mia | XXX |
+----+---------+------------+--------+---------+
Table 2 (posts)
+-----+-------------+---------------------+---------+
| id | category_id | name | content |
+-----+-------------+---------------------+---------+
| 1 | 1 | some random name | xxxxxxx |
| 2 | 2 | another random name | xxxxxxx |
| 3 | 1 | third random name | xxxxxxx |
+-----+-------------+---------------------+---------+
我的目标是获得一个列表,其中包含来自特定 category_id
的每个 post 的最新评论。
因此,例如,如果我将类别 1 作为输入,我需要 ID 为 2 和 1 的评论,因为这些始终是给定类别的每个 post 的最后评论。
到目前为止,我得到了这个查询,其中 returns 所有条目都按创建日期排序。
select *
from comments c
join posts p on c.post_id = p.id
where p.category_id = 1
order by c.created_at desc;
我已经阅读了有关 group by
属性 的信息,但这并不能保证我能获得最后的条目。我该如何解决这个问题?
假设 Table2
是 类别 table,如果您只想在结果中包含 Table1
的列,那么您不需要不需要加入。
使用 NOT EXISTS
:
select t1.*
from table_1 t1
where not exists (
select 1 from table_1
where table2_id = t1.table2_id and created_at > t1.created_at
)
或相关子查询:
select t1.*
from table_1 t1
where t1.created_at = (select max(created_at) from table_1 where table2_id = t1.table2_id)
编辑:
select c.*
from posts p inner join (
select c.* from comments c
where not exists (
select 1 from comments
where post_id = c.post_id and created_at > c.created_at
)
) c on c.post_id = p.id
where p.category_id = ?
参见demo。
或者:
select c.*
from posts p inner join (
select c.* from comments c
where c.post_id in (select id from posts where category_id = ?)
and not exists (
select 1 from comments
where post_id = c.post_id and created_at > c.created_at
)
) c on c.post_id = p.id
参见demo。
将 ?
替换为您要搜索的 category_id
。
结果:
| id | post_id | created_at | author | content |
| --- | ------- | ------------------- | ------ | ------- |
| 1 | 3 | 2020-03-01 00:00:00 | Jack | XXX |
| 2 | 1 | 2020-02-29 00:00:00 | Joe | XXX |
将 GROUP BY
与聚合函数 MAX
结合使用应该可以解决您的问题:
SELECT
b.id AS category_id,
MAX(a.created_at) AS last_created
FROM table_1 a
JOIN table_2 b on a.table2_id = b.id
GROUP BY b.id
ORDER BY last_created DESC;