Получение последних сообщений в категории на форуме - PullRequest
0 голосов
/ 20 марта 2019

Я пытаюсь создать SQL-запрос, который будет извлекать каждую категорию из БД и объединять их с последним сообщением в категории.

Я использую MySQL

Иерархия содержимого такова

Категория> Форум> Сообщения

и это описание этих таблиц

Категория

+-------+---------------------------+------+-----+---------+----------------+
| Field | Type                      | Null | Key | Default | Extra          |
+-------+---------------------------+------+-----+---------+----------------+
| id    | int(10) unsigned          | NO   | PRI | NULL    | auto_increment |
| title | varchar(100)              | NO   |     | NULL    |                |
| icon  | varchar(100)              | NO   |     | NULL    |                |
| color | set('red','green','pink') | NO   |     | NULL    |                |
+-------+---------------------------+------+-----+---------+----------------+

Форум

+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| title       | varchar(100)     | NO   |     | NULL    |                |
| subtitle    | varchar(100)     | NO   |     | NULL    |                |
| category_id | int(10) unsigned | NO   | MUL | NULL    |                |
+-------------+------------------+------+-----+---------+----------------+

Сообщения

+------------+------------------+------+-----+------------------------+
| Field      | Type             | Null | Key | Default|  Extra        |
+------------+------------------+------+-----+--------+---------------+
| id         | int(10) unsigned | NO   | PRI | NULL   |auto_increment |
| title      | varchar(100)     | NO   |     | NULL   |               |
| content    | longtext         | NO   |     | NULL   |               |
| forum_id   | int(10) unsigned | NO   | MUL | NULL   |               |
| slug       | varchar(100)     | NO   | MUL | NULL   |               |
| created_at | timestamp        | NO   |     | TS     |               |
| updated_at | timestamp        | NO   |     | 0000   | on update CTP |
+------------+------------------+------+-----+------------------------+

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

SELECT *
FROM   (SELECT `categories`.`id`,
               `posts`.`title`      AS post_title,
               `categories`.`title` AS cat_title,
               `posts`.`created_at` AS created
        FROM   `categories`
               JOIN `forums`
                 ON `forums`.`category_id` = `categories`.`id`
               JOIN `posts`
                 ON `posts`.`forum_id` = `forums`.`id`
        ORDER  BY `created` DESC
        LIMIT  18446744073709551615) AS sub
GROUP  BY `id`  

=================== EDIT ====================

Таблица категорий образцов

+------------------------+-----------+----------+
| id| title              | icon      | color    |
+------------------------+-----------+----------+
| 1 | General Forums     | fa-pencil | red      |
| 2 | Help & Disscussion | fa-person | blue     | 
+---+--------------------+--------+------+------+

Пример таблицы форума

+------------------------------+----------------------+--------------+
| id| title                    | subtitle             | category_id  |
+------------------------------+----------------------+--------------+
| 1 | Software Development     | About software dev   | 1            |
+---|--------------------------|----------------------|--------------|
| 2 | Graphics Design          | About graphics des   | 2            |
+---+--------------------------+-----------+----------+--------------|

Пример таблицы сообщений

+---+---------------------+----------------------------+----------------------------------+
| id| title               | content         | forum_id | slug       | created_at          |
+-------------------------+----------------------------+----------------------------------+
| 1 | Memoizing in JS     | Lorem Ipsum     | 1        |  memo-js   | 2019-03-21 00:45:54 |
+---+---------------------+----------------------------+------------+---------------------+
| 2 | Using headers in C# | Lorem Ipsum     | 1        | using-he   | 2019-03-20 00:45:54 |
+---+---------------------+-----------------+----------+----------------------------------+

Так что для каждой категории мне нужен последний пост на основе даты создания

Это дамп базы данных здесь

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Это абсолютно не правильный путь. Вы используете GROUP BY с SELECT *, который не поддерживается большинством баз данных и даже не поддерживается более поздними версиями MySQL с использованием настроек по умолчанию.

Вместо того, чтобы:

SELECT c.id, p.title as post_title, c.title as cat_title,
       p.created_at AS created
FROM categories c JOIN
     forums f
     ON f.category_id = c.id JOIN
     posts p
     ON p.forum_id = f.id
WHERE p.created_at = (SELECT MAX(p2.created_at)
                      FROM posts p2 JOIN
                           forums f2
                           ON p2.forum_id = f2.id
                      WHERE f2.category_id = f.category_id
                     )
ORDER  BY created_at DESC;

Подзапрос вычисляет максимальное значение, созданное на дату для сообщений для данной категории.

0 голосов
/ 20 марта 2019

Это должно дать то, что вы хотите.

SELECT *
FROM (
  SELECT c.id, p.title AS post_title, c.title AS cat_title, p.created_at AS created
      , ROW_NUMBER() OVER(PARTITION BY c.id ORDER BY p.created_at) AS rn
  FROM categories c
  JOIN forums f ON f.category_id = c.id
  JOIN posts p ON p.forum_id = f.id
) a
WHERE rn = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...