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

Ссылка скопирована
1 ответ

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

Дополнительно:

Пока на ум приходит получить все категории, потом в цикле пройтись по ним и...

Естественно это не делается так. Такие задачи решаются на стороне бд через джоин таблиц. Не считая ошибки синтаксиса и отсутствия лимита, запрос в ответе Vindicar подойдет. Схема хранения не самая лучшая, так как по сути у вас получается один-ко-многим (одна категория ко многим постам), и если категорий на 1 пост будет больше 1, вся структура идет в мусор. Более качественным решением все же будет многие-ко-многим между постами и категориями.

  • Спасибо!

Чем не устраивает

SELECT * FROM Categories LEFT JOIN Posts ON Posts.category_id = Categories.id ORDER BY Categories.id ASC

SELECT * FROM Categories LEFT JOIN Posts ON Posts.category_id = Categories.id ORDER BY Categories.id ASC

?
Тогда посты из одной категории будут идти последовательно. Запоминаешь категорию предыдущего поста, при обработке следующего поста сравниваешь. Если не совпадает - закрываешь теги для предыдущей категории, открываешь теги для новой категории.

  • SELECT *
    FROM Categories
    LEFT JOIN Posts
    ON Posts.category_id ==(?) Categories.id
    ORDER BY Categories.id ASC

  • ThunderCat, ох. Поправил.
  • Спасибо большое!

Ответы:

Если данных в каждой категории немного - то оверхед от дублирования в каждой строке результата небольшой, и ответ Vindicar прекрасен.
Если оверхед большой, то:

  1. получаете первым запросом категории,
  2. сохраняете в какую-то структуру, где ключом служит id категории,
  3. выбираете посты одним запросом, с фильтром по id нужных категорий,
  4. в процессе разбора результатов этого запроса, распихиваете посты сразу по нужным категориям.
  • Спасибо, Михаил!

В синтаксисе 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

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 - то это пост, и он рисуется со смещением.

Дурь, конечно, но для сельской местности сойдёт..

  • Спасибо!
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Павел Админов Ответ

Для выполнения SQL запроса из двух таблиц необходимо использовать оператор JOIN. JOIN позволяет объединить данные из двух или более таблиц на основе определенного условия. В зависимости от типа JOIN (INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN) будут выбираться различные записи из таблиц.

Пример SQL запроса с использованием INNER JOIN:

SELECT table1.column1, table2.column2
FROM table1
INNER JOIN table2 ON table1.common_column = table2.common_column;

SELECT table1.column1, table2.column2 FROM table1 INNER JOIN table2 ON table1.common_column = table2.common_column;

В данном примере мы выбираем данные из двух таблиц table1 и table2, объединенных по общему столбцу common_column. INNER JOIN вернет только те строки, у которых есть соответствующие значения в обеих таблицах.

Если нужно добавить условие для фильтрации данных, можно использовать WHERE:

SELECT table1.column1, table2.column2
FROM table1
INNER JOIN table2 ON table1.common_column = table2.common_column
WHERE table1.column3 = 'value';

SELECT table1.column1, table2.column2 FROM table1 INNER JOIN table2 ON table1.common_column = table2.common_column WHERE table1.column3 = 'value';

Также можно использовать другие типы JOIN (LEFT JOIN, RIGHT JOIN, FULL JOIN) в зависимости от требуемой логики объединения данных из таблиц.

Надеюсь, данное объяснение поможет вам выполнить SQL запрос из двух таблиц. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно