MySQL: несколько фотографий и видео для новостей с объединениями - PullRequest
2 голосов
/ 06 сентября 2010

Я хочу multiple photos и multiple videos, главная проблема в том, что я не могу получить их inline, если я не использую объединения.

Так, например,, Я получаю 2 photos a video и снова photo.

У меня есть родительская таблица news и 2 дополнительные таблицы news_photos и news_videos, и я хочу войти в one query photos и videos для news.

Это как-то возможно?

mysql_query("
    SELECT * 
    FROM news_photos, news_videos 
    FULL JOIN news_videos 
    ON news_id = {$news_id}
    FULL JOIN news_photos
    ON news_id = {$news_id}
");

Изображение о структуре: alt text

Ответы [ 2 ]

2 голосов
/ 06 сентября 2010

На самом деле в нем только одно ПОЛНОЕ СОЕДИНЕНИЕ, поскольку вы вообще не используете таблицу news.

SELECT *  
FROM news_photos  
FULL JOIN news_videos  
ON news_photos.news_id=news_videos.news_id
WHERE news_photos.news_id=... OR news_videos.news_id=...

FULL JOIN не поддерживается MySQL. Это может быть менее эффективно смоделировано с использованием двух LEFT JOIN и UNION, но это действительно редко требуется. Предполагая, что каждое фото и видео относится к новостям, вы можете избежать их и получить более обычный запрос, добавив в него таблицу news:

SELECT *
FROM news
LEFT JOIN news_photos ON news_photos.news_id=news.id
LEFT JOIN news_videos ON news_videos.news_id=news.id
WHERE news_id=...

Но, тем не менее, это почти наверняка не то, что вы имеете в виду! Если для новости есть несколько фотографий и видео, вы бы эффективно создали декартово произведение, в котором каждая комбинация фото и видео создает ряд. Такого рода комбинаторный взрыв вам почти не нужен!

Если вам нужно только одно из каждого фото и видео, я полагаю, вы могли бы взломать это в одном запросе, используя LEFT JOIN, который всегда будет давать NULL с другой стороны:

SELECT * FROM news_photos
LEFT JOIN news_videos ON 0
WHERE news_photos.news_id=...
UNION SELECT * FROM news_photos
RIGHT JOIN news_videos ON 0
WHERE news_videos.news_id=...

Но на самом деле это ничего не даст. Не объединяйте два отдельных запроса («Я хочу, чтобы фотографии для новостей и видео для новостей») в один. Просто сделайте это тривиальным способом:

SELECT * FROM news_photos
WHERE news_id=...

SELECT * FROM news_videos
WHERE news_id=...
0 голосов
/ 06 сентября 2010

Я бы сделал это с помощью хранимой процедуры, которая имела несколько операторов выбора следующим образом:

http://pastie.org/1141100

drop procedure if exists list_news_photos_videos;

delimiter #

create procedure list_news_photos_videos
(
in p_news_id int unsigned
)
proc_main:begin

 select n.* from news n where n.news_id = p_news_id;

 select p.* from news_photos p where p.news_id = p_news_id order by photo_id desc;

 select v.* from news_videos v where v.news_id = p_news_id order by video_id desc;

end proc_main #

Вы бы назвали это в MySQL следующим образом:

call list_news_photos_videos (2);

затем вы можете вызвать хранимую процедуру из php (только вызов 1 дБ), используя mysqli следующим образом:

http://pastie.org/1141103

<?php
// quick and dirty demo - needs to be made more robust !!

$db = new Mysqli("localhost", "foo_dbo", "pass", "foo_db");

$sql = sprintf("call list_news_photos_videos(%d)", 2); // get all the news related data in one query

$result = $db->query($sql);

//news item
$row = $result->fetch_assoc();

echo sprintf("<h2>news item</h2>news_id = %d subject = %s <br/>", $row["news_id"], $row["subject"]);

$result->free();

//news photos
$db->next_result();
$result = $db->use_result();

echo "<h2>news photos</h2>";

while ($row = $result->fetch_assoc()){
    echo sprintf("photo_id = %d subject = %s<br/>", $row["photo_id"], $row["subject"]);
}

$result->free();

//news videos
$db->next_result();
$result = $db->use_result();

echo "<h2>news videos</h2>";

while ($row = $result->fetch_assoc()){
    echo sprintf("video_id = %d subject = %s<br/>", $row["video_id"], $row["subject"]);
}

$result->free();
$db->close();

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