MySQL Group By для отсортированной таблицы - PullRequest
0 голосов
/ 01 марта 2020

У меня есть две таблицы с этими структурами:

Таблица 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     |
+----+---------+------------+--------+---------+

Таблица 2 (сообщения)

+-----+-------------+---------------------+---------+
| id  | category_id |        name         | content |
+-----+-------------+---------------------+---------+
|   1 |           1 | some random name    | xxxxxxx |
|   2 |           2 | another random name | xxxxxxx |
|   3 |           1 | third random name   | xxxxxxx |
+-----+-------------+---------------------+---------+

Моя цель - получить список с последним комментарием к каждому сообщению определенного c category_id.

Так, например, если у меня есть категория 1 в качестве входных данных, мне нужны комментарии с id 2 и 1, потому что это всегда последние комментарии для каждого сообщения с данной категорией.

До сих пор , Я получил этот запрос, который возвращает все записи, упорядоченные по дате создания.

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, но это не гарантирует, что я получу последние записи. Как я могу решить эту проблему?

Ответы [ 2 ]

1 голос
/ 01 марта 2020

Предполагая, что Table2 является таблицей категории , если вы хотите в результатах только столбцы 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 = ?

См. Демонстрационную версию . Или:

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

См. Демоверсию . Замените ? на 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     |
0 голосов
/ 01 марта 2020

Использование 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;
...