Получить все сообщения из определенной категории - PullRequest
1 голос
/ 03 июля 2011

Ситуация

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

На этот раз я застрял в получении всех сообщений из определенной категории, с их категорией.

База данных

Вот SQL-команды для создания трех обязательных таблиц.

Сообщение

create table Post(
    headline varchar(100),
    date datetime,
    content text,
    author int unsigned,
    public tinyint,
    type int,
    ID serial,
    Primary Key (ID),
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

author - это идентификатор пользователя, создавшего публикацию, public определяет, можно ли прочитать сообщение от всех или является черновиком, а type определяет, является ли это запись в блоге (0) или что-то еще.

Категория

create table Kategorie(
    name varchar(30),
    short varchar(200),
    ID serial,
    Primary Key (name)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Post_Kategorie

create table Post_Kategorie(
    post_ID bigint unsigned,
    kategorie_ID bigint unsigned,
    Primary Key (post_ID, kategorie_ID),
    Foreign Key (post_ID) references Post(ID),
    Foreign Key (kategorie_ID) references Kategorie(ID)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Запрос

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

SELECT Post.headline, Post.date, Post.ID,
  CONCAT(
    "[", GROUP_CONCAT('{"name":"',Kategorie.name,'","id":',Kategorie.ID,'}'), "]"
  ) as "categorys"
FROM Post
INNER JOIN Post_Kategorie
  ON Post.ID = Post_Kategorie.post_ID
INNER JOIN Kategorie
  ON Post_Kategorie.kategorie_ID = 2
WHERE Post.public = 1
  AND Post.type = 0
GROUP BY Post.headline, Post.date
ORDER BY Post.date DESC
LIMIT 0, 20

Запрос работает для перечисления всех постов, помеченных определенной категорией, но столбец categorys смешивается, так как у каждого перечисленного поста есть все доступные категории (все категории, перечисленные в таблице Kategorie).

Я уверен, что проблема заключается в INNER JOIN -условии, но я понятия не имею, где. Пожалуйста, направьте меня в правильном направлении.

1 Ответ

1 голос
/ 03 июля 2011

Я подозреваю, что могут быть проблемы с вашей функцией CONCAT, так как она смешивает разные типы кавычек.Я думаю, что "[" и "]" должны быть соответственно '[' и ']'.

В противном случае проблема, похоже, связана с одним из объединений.В частности, INNER JOIN Kategorie не определяет условие соединения, которое, я думаю, должно быть Post_Kategorie.Kategorie_ID = Kategorie.ID.

Таким образом, весь запрос должен выглядеть примерно так:

SELECT Post.headline, Post.date, Post.ID,
  CONCAT(
    "[", GROUP_CONCAT('{"name":"',Kategorie.name,'","id":',Kategorie.ID,'}'), "]"
  ) as "categorys"
FROM Post
INNER JOIN Post_Kategorie
  ON Post.ID = Post_Kategorie.post_ID
INNER JOIN Kategorie
  ON Post_Kategorie.Kategorie_ID = Kategorie.ID
WHERE Post.public = 1
  AND Post.type = 0
GROUP BY Post.headline, Post.date
HAVING MAX(CASE Post_Kategorie.kategorie_ID WHEN 2 THEN 1 ELSE 0 END) = 1
ORDER BY Post.date DESC
LIMIT 0, 20

Условие Post_Kategorie.kategorie_ID = 2 было изменено на выражение CASE и перемещено в предложение HAVING, и оно используется вместе с агрегатной функцией MAX().Это работает следующим образом:

  • Если сообщение помечено тегом или тегами, относящимися к Kategorie.ID = 2, выражение CASE вернет 1, а MAX также оценивается в 1.Следовательно, вся группа будет действительной и останется в выходных данных.

  • Если ни один тег, которым помечено сообщение, не относится к указанной категории, выражение CASE никогда не будет иметь значения 1 илибудет макс.В результате вся группа будет отброшена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...