Выберите данные из нескольких таблиц, если контент существует, или пропустите одну таблицу
У меня есть php-страница с галереей. Под всеми пунктами я печатаю некоторую информацию, такую как хорошие / плохие голоса (большие пальцы вверх / вниз) и количество просмотров.
Для каждой вставленной строки в содержимом также будет строка, вставленная в таблицу content_views. Однако таблица голосов будет содержать только строки, если кто-то проголосовал (1vote = 1row).
Я хочу выделить всю информацию (контент.*, Просмотры и голоса, если есть) в определенной категории (нише). У меня проблема в том, что мой запрос (см. Ниже) вернет пустой результат, если нет голосов.
$result = mysql_query("
SELECT content.*, content_views.views as views, votes.good, votes.bad
FROM content, content_niches, content_views , votes
WHERE content_views.content = content.record_num
AND content.approved = 2
AND content_niches.content = content.record_num
AND votes.content = content.record_num
AND content_niches.niche = '$niche'
AND content.enabled = 1
GROUP BY content.record_num
ORDER BY $orderby DESC LIMIT $from,$max_results") or die(mysql_error());
Конечно, я могу сделать следующее, но так как у меня>50К строк по содержанию и еще больше по голосам, это будет очень медленно.
$result = mysql_query("
SELECT content.*, content_views.views as views,
(SELECT votes.good FROM votes WHERE votes.content=content.record_num) AS good,
(SELECT votes.bad FROM votes WHERE votes.content=content.record_num) AS bad
FROM content, content_niches, content_views
WHERE content_views.content = content.record_num
AND content.approved = 2
AND content_niches.content = content.record_num
AND votes.video = content.record_num
AND content_niches.niche = '$niche'
AND content.enabled = 1
GROUP BY content.record_num
ORDER BY $orderby DESC LIMIT $from,$max_results") or die(mysql_error());
Каков "правильный" способ сделать это?
Edit1: новый запрос, который слишком медленный, что делать?
$result = mysql_query("
SELECT content.*,content_niches.*, content_views.views as views
FROM content
INNER JOIN
content_niches ON (content_niches.content = content.record_num AND content_niches.niche = '$chanid')
INNER JOIN
content_views ON (content_views.content = content.record_num )
LEFT OUTER JOIN votes
ON (votes.video = content.record_num)
WHERE content.approved = 2
AND content.enabled = 1
GROUP BY content.record_num
ORDER BY $orderby DESC LIMIT $from,$max_results") or die(mysql_error());
1 ответ
Это называется outer join
, Левое внешнее соединение возвращает все строки с левой стороны и только те, которые совпадают с правой стороны.
Так, например, если у вас есть пост с 1 голосом и пост с 0 голосами, и вы делаете это:
select *
from posts
left outer join votes
on posts.id = votes.id
Он вернул бы все сообщения и любые записи голосов, которые существуют и соответствуют.
Вы действительно должны научиться использовать синтаксис ANSI-соединения вместо не ANSI-объединений