У меня есть страница, которая отображает список проектов. С каждым проектом отображаются следующие данные, полученные из базы данных mysqli:
Проекты отображаются 6 на страницу с использованием системы нумерации страниц
Поскольку это основано на моем старом проекте, изначально оно было сделано с неаккуратным кодом (я только учился и не знал ничего лучше), используя много запросов. Три, фактически, только для пунктов 5-7, и они содержались в цикле while, который работал с системой нумерации страниц. Теперь я прекрасно понимаю, что это даже не то, что нужно для ведения бизнеса.
Я знаком с INNER JOIN и использованием подзапросов, но меня беспокоит, что я не смогу получить все эти данные, используя только один запрос select, по следующим причинам:
Пункты 1-4 достаточно просты с базовым SELECT
запрос, НО …
Пункт 5 нуждается в SELECT COUNT
А ТАКЖЕ…
Пункт 6 нуждается в базовом SELECT
запрос с ORDER by RAND LIMIT 1
в
выберите одну случайную фотографию из всех, связанных с каждым проектом
(об использовании FilesystemIterator не может быть и речи, потому что фотографии
В таблице есть столбец, показывающий 0, если фотография неактивна, и 1, если она
активный)
Элемент 7 выбран из таблицы перекрестных ссылок для тегов и
проекты и таблица, содержащая идентификатор тега и имена
Учитывая это, я не уверен, может ли все это (или даже должно быть) в этом случае всего лишь одним запросом, или для этого потребуется более одного запроса. Я неоднократно читал, как стоит потрясти носом газету, чтобы вставить один или несколько запросов в цикл while. Я даже читал, что множественные запросы — вообще плохая идея.
Так что я застрял. Я понимаю, что это может показаться слишком общим, но у меня нет кода, который работает, только старый код, который использует 4 запроса для выполнения работы, 3 из которых вложены в цикл while.
Структура базы данных ниже.
Таблица проектов:
+-------------+---------+----------+---------------+------+
| project_id | title | subtitle | description | part |
|---------------------------------------------------------|
| 1 | Chevy | Engine | Modify | 1 |
| 2 | Ford | Trans | Rebuild | 1 |
| 3 | Mopar | Diff | Swap | 1 |
+-------------+---------+----------+---------------+------+
Фотографий стол:
+----------+------------+--------+
| photo_id | project_id | active |
|--------------------------------|
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 1 |
| 4 | 2 | 1 |
| 5 | 2 | 1 |
| 6 | 2 | 1 |
| 7 | 3 | 1 |
| 8 | 3 | 1 |
| 9 | 3 | 1 |
+----------+------------+--------+
Таблица тегов:
+--------+------------------+
| tag_id | tag |
|---------------------------|
| 1 | classic |
| 2 | new car |
| 3 | truck |
| 4 | performance |
| 5 | easy |
| 6 | difficult |
| 7 | hard |
| 8 | oem |
| 9 | aftermarket |
+--------+------------------+
Таблица перекрестных ссылок тегов / проектов:
+------------+-----------+
| project_id | tag_id |
|------------------------|
| 1 | 1 |
| 1 | 3 |
| 1 | 4 |
| 2 | 2 |
| 2 | 5 |
| 3 | 6 |
| 3 | 9 |
+------------+-----------+
Я не прошу, чтобы код был написан для меня, но если то, что я спрашиваю, имеет смысл, я искренне оценил бы толчок в правильном направлении. Часто я борюсь с онлайн-руководствами по PHP и MySQLi, поэтому, если есть какой-то способ разобраться в этом, то это фантастика.
Большое спасибо всем вам.
Вы можете делать подзапросы внутри вашего SELECT
оговорка, как это:
SELECT
p.title, p.subtitle, p.description, p.part,
(SELECT COUNT(photo_id) FROM Photos where project_id = p.project_id) as total_photos,
(SELECT photo_id FROM Photos where project_id = p.project_id ORDER BY RAND LIMIT 1) as random_photo
FROM projects as p
Теперь для списка тегов, так как он возвращает более одной строки, вы не можете сделать подзапрос, и вы должны сделать один запрос для каждого проекта. Ну, на самом деле вы можете, если вы вернете все теги в какой-то форме, например, через список, разделенный запятыми: tag1, tag2, tag3 … но я не рекомендую это один раз, когда вам нужно будет взорвать значение столбца , Делайте это только в том случае, если у вас много проектов, а производительность для получения списка тегов для каждого отдельного проекта довольно низкая. Если вы действительно хотите, вы можете:
SELECT
p.title, p.subtitle, p.description, p.part,
(SELECT COUNT(photo_id) FROM Photos where project_id = p.project_id) as total_photos,
(SELECT photo_id FROM Photos where project_id = p.project_id ORDER BY RAND LIMIT 1) as random_photo,
(SELECT GROUP_CONCAT(tag SEPARATOR ', ') FROM tags WHERE tag_id in (SELECT tag_id FROM tagproject WHERE project_id = p.project_id)) as tags
FROM projects as p
Как вы сказали в пунктах 1-4, у вас уже есть решение.
Добавить к тому же запросу SQL_CALC_FOUND_ROWS
вместо SELECT COUNT
решить пункт 5.
Для пункта 6 вы можете использовать подзапрос или может быть LEFT JOIN
ограничение до одного результата.
Для самого последнего элемента вы также можете использовать подзапрос, объединяющий все теги в один результат (например, через запятую).