MySQL:连接新闻的多个照片和视频

时间:2010-09-06 08:04:40

标签: php mysql database join

我想要multiple photosmultiple videos,主要问题是如果我不使用联接,我就无法获取inline

例如,我得到2 photos一个video,再来一个photo

我有一个父news表和两个辅助表news_photosnews_videos,我想进入one query photosvideos } 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 个答案:

答案 0 :(得分:2)

实际上只有一个FULL JOIN,因为你根本没有涉及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=...

MySQL不支持FULL JOIN。使用两个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=...

答案 1 :(得分:0)

我会使用具有多个select语句的存储过程来执行此操作,如下所示:

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);

然后你可以使用mysqli从php调用存储过程(仅限1分贝调用),如下所示:

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();

?>