@Kumatoz48

Как сделать SQL запрос из двух таблиц?

Здравствуйте. Есть база данных, в ней две таблицы. Таблица posts содержит поля id, name, title, category_id и т.д. Таблица categories содержит поля id, name и т.д. Логика простая, каждый пост принадлежит какой-то (одной) категории. Category_id в таблице posts - это id категории, к которой этот пост принадлежит.
Необходимо получить все категории и все принадлежащие им посты, чтобы вывести на странице (типа древовидной структуры:
Категория1
-пост1
-пост2
Категория2
-пост3
-пост4
-пост5
...
Пока на ум приходит получить все категории, потом в цикле пройтись по ним и на каждой итерации делать запрос к таблице posts для получения постов из этой категории. Но понимаю, что это глупо и очень медленно. Второй вариант - получить сразу двумя запросами все посты и все категории, а потом уже на php посты раскидать по категориям. Так запросов будет мало, но будут вложенные циклы. Думаю это тоже не самое оптимальное решение. Хотелось бы услышать варианты наиболее оптимального решения данной задачи. Спасибо.
  • Вопрос задан
  • 271 просмотр
Решения вопроса 2
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Пока на ум приходит получить все категории, потом в цикле пройтись по ним и...

Естественно это не делается так. Такие задачи решаются на стороне бд через джоин таблиц. Не считая ошибки синтаксиса и отсутствия лимита, запрос в ответе Vindicar подойдет. Схема хранения не самая лучшая, так как по сути у вас получается один-ко-многим (одна категория ко многим постам), и если категорий на 1 пост будет больше 1, вся структура идет в мусор. Более качественным решением все же будет многие-ко-многим между постами и категориями.
Ответ написан
Vindicar
@Vindicar
RTFM!
Чем не устраивает
SELECT * FROM Categories LEFT JOIN Posts ON Posts.category_id = Categories.id ORDER BY Categories.id ASC

?
Тогда посты из одной категории будут идти последовательно. Запоминаешь категорию предыдущего поста, при обработке следующего поста сравниваешь. Если не совпадает - закрываешь теги для предыдущей категории, открываешь теги для новой категории.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Если данных в каждой категории немного - то оверхед от дублирования в каждой строке результата небольшой, и ответ Vindicar прекрасен.
Если оверхед большой, то:
  1. получаете первым запросом категории,
  2. сохраняете в какую-то структуру, где ключом служит id категории,
  3. выбираете посты одним запросом, с фильтром по id нужных категорий,
  4. в процессе разбора результатов этого запроса, распихиваете посты сразу по нужным категориям.
Ответ написан
@Akina
Сетевой и системный админ, SQL-программист.
В синтаксисе MySQL:
SELECT c.name category_name, p.id post_id, p.name post_name, p.title post_title
FROM posts p
JOIN categories c ON p.category_id = c.id
UNION ALL
SELECT name, NULL, NULL, NULL
FROM categories 
ORDER BY category_name, post_id IS NOT NULL

Соответственно если в поле post_id обнаруживается NULL, то в этой записи категория, и она рисуется как категория. Если же там не NULL - то это пост, и он рисуется со смещением.

Дурь, конечно, но для сельской местности сойдёт..
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы