这是我的SQL小提琴:SQL Fiddle
我试图用PHP回应这个结果。这是我的预期结果:
// Some Stuff Here
The Dark Knight Rises - 7.5
Batman Begins - 7.5
Iron Man - 7.3
The Lord of the Rings: The Return of the King - 8.1
etc...
// Some more Stuff here
我的PHP代码:
$stmt = $conn->prepare("SELECT tmdb_movies.movie_title
,GROUP_CONCAT(recommendations.recommendations_title ORDER BY recommendations.recommendations_title) as recommendations_title
,GROUP_CONCAT(recommendations.recommendations_vote_average ORDER BY recommendations.recommendations_title) as recommendations_vote_average
FROM tmdb_movies
LEFT JOIN cast ON cast.cast_tmdb_id=tmdb_movies.tmdb_id
LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id
Where tmdb_movies.tmdb_id= 155
GROUP BY tmdb_movies.movie_title
");
// Then fire it up
$stmt->execute();
// Pick up the result as an array
$result = $stmt->fetchAll();
// Now you run through this array in many ways, for example
for($x=0, $n=count($result); $x < $n; $x++){
$recommendations_name_list = explode(',',$result[$x]["recommendations_title"]);
$recommendations_vote_average = explode(',',$result[$x]["recommendations_vote_average"]);
foreach( $recommendations_name_list as $index => $recommendations_title ) {
echo'
<p>'.$recommendations_title.'- '.$recommendations_vote_average[$index].'</p>';
}
}
<小时/> 输出此代码:
Batman Begins- 7.5
Batman Begins- 7.5
Batman Begins- 7.5
Batman Begins- 7.5
Batman Begins- 7.5
Batman Begins- 7.5
Batman Begins- 7.5
Batman Begins- 7.5
Batman Begins- 7.5
Batman Begins- 7.5
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Captain America: The First Avenger- 6.6
Inception- 8
Inception- 8
Inception- 8
Inception- 8
Inception- 8
Inception- 8
Inception- 8
Inception- 8
Inception- 8
Inception- 8
Iron Man- 7.3
Iron Man- 7.3
Iron Man- 7.3
Iron Man- 7.3
Iron Man- 7.3
Iron Man- 7.3
Iron Man- 7.3
Iron Man- 7.3
Iron Man- 7.3
Iron Man- 7.3
Iron Man 2- 6.6
Iron Man 2- 6.6
Iron Man 2- 6.6
Iron Man 2- 6.6
Iron Man 2- 6.6
Iron Man 2- 6.6
Iron Man 2- 6.6
Iron Man 2- 6.6
Iron Man 2- 6.6
Iron Man 2- 6.6
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Dark Knight Rises- 7.5
The Lord of th- 8
但如果我删除此行LEFT JOIN cast ON cast.cast_tmdb_id=tmdb_movies.tmdb_id
那么,我的PHP代码工作正常。
预期结果:
Batman Begins- 7.5
Captain America: The First Avenger- 6.6
Inception- 8
Iron Man- 7.3
Iron Man 2- 6.6
The Dark Knight Rises- 7.5
The Lord of the Rings: The Fellowship of the Ring- 8
The Lord of the Rings: The Return of the King- 8.1
The Lord of the Rings: The Two Towers- 7.9
The Matrix- 7.9
答案 0 :(得分:0)
使用LEFT JOIN cast
对于选择值是不可用的(结果是选择ayway,因为它们基于maun table movie_title
adn不返回有用的信息,因为select子句中没有di table中的列,并生成一个包含更多行的结果集
所以,如果你想坚持左边的连接,你可以将DISTINCT添加到你的原始查询
SELECT DISTICNT
tmdb_movies.movie_title
,GROUP_CONCAT(recommendations.recommendations_title
ORDER BY recommendations.recommendations_title) as recommendations_title
,GROUP_CONCAT(recommendations.recommendations_vote_average
ORDER BY recommendations.recommendations_title) as recommendations_vote_average
FROM tmdb_movies
LEFT JOIN cast ON cast.cast_tmdb_id=tmdb_movies.tmdb_id
LEFT JOIN recommendations
ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id
Where tmdb_movies.tmdb_id= 155
GROUP BY tmdb_movies.movie_title
或者更好地使用left join pn cast
SELECT
tmdb_movies.movie_title
,GROUP_CONCAT(recommendations.recommendations_title
ORDER BY recommendations.recommendations_title) as recommendations_title
,GROUP_CONCAT(recommendations.recommendations_vote_average
ORDER BY recommendations.recommendations_title) as recommendations_vote_average
FROM tmdb_movies
LEFT JOIN recommendations
ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id
Where tmdb_movies.tmdb_id= 155
GROUP BY tmdb_movies.movie_title
答案 1 :(得分:0)
您帖子中的许多内容都没有加起来。你的sql小提琴完全错过了演员表。我已经评论过您正在使用GROUP_CONCAT。您的问题没有完整的信息来帮助我们了解您的问题。
话虽如此,我相信我已经推测出了你真正想要的东西。主要问题是您的GROUP BY应包括原始电影和推荐电影。这将为每组电影/推荐组合返回一行。您可以使用GROUP_CONCAT在一列中获取强制转换。此外,我认为你想要的演员数据实际上是推荐电影的演员阵容,而不是原始电影的演员阵容。您可以将两者结合在一起,但在此查询的上下文中,在我看来,您希望将推荐影片的强制转换组合到GROUP_CONCAT的一列中。正如我对您所评论的那样,问题是您在推荐表中没有推荐的电影的tmdb_id。坦率地说,这是一个非规范化的结构(存储标题而不是id),并且在关系上是错误的,浪费的并且可能令人困惑。
为什么会这样?
首先,推荐表没有主键,需要一个。标题也不是一个好的候选键,因为有许多电影具有相同的标题。使用您的系统,无法确定哪些电影可能具有相同的标题。因此,您应该拥有的是tmdb_id作为外键,此时,您不需要(也不想要)标题,因为它可以从tmdb_movies表中获取。您的推荐表基本上是一个多对多表,它以父对子的方式将电影相互关联。除了外键(tmdb_id,recommended_tmdb_id)之外,实际上不需要在表中包含任何其他内容,因为您当前拥有的值(标题,平均等级)是存储在tmdb_movies表中的非规范化值。
现在想想未来,也许你有成千上万的电影,每部电影可能有10部与之相关的推荐电影。你将浪费任何一部电影,兆字节的数据库存储重复相同的标题和平均值,不会改变。更糟糕的是,平均值是时间的快照。无论何时需要重新计算平均评级,而不是更新tmdb_movie表的一行中的单个值,您现在必须更新推荐中将该电影推荐给原始电影的每一行。这些是去标准化的一些成本。
现在来看GROUPing的细节。
首先说明GROUP BY的工作方式,我建议你在sqlfiddle或live db中运行这些查询:
SELECT tmdb_movies.movie_title, recommendations.recommendations_title, recommendations.recommendations_vote_average
FROM tmdb_movies
LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id
GROUP BY tmdb_movies.tmdb_id, recommendations.recommendations_title
Where tmdb_movies.tmdb_id=1
与您一直在做的关键是,我删除了无用的GROUP_CONCAT语句,并在tmdb_movies.tmdb_id,recommendations.recommendations_title上执行了GROUP BY。
理想情况下,这可能是由id,但我在上面介绍过,所以现在我们必须使用标题。
正如您所看到的,每个独特的Movie&amp;组合都会获得一个GROUP。推荐电影。看来这就是你想要的。请注意,我根本没有使用GROUP_CONCAT,而是获得平均值和标题,每行一个。
现在让我们假设您也想加入演员表。
我们将其添加到:
SELECT tmdb_movies.movie_title, recommendations.recommendations_title, recommendations.recommendations_vote_average
FROM tmdb_movies
LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id
LEFT JOIN cast ON cast.recommendations_title=recommendations.recommendations_title
GROUP BY tmdb_movies.tmdb_id, recommendations.recommendations_title
请注意,没有变化。你不会得到无关的行,因为GROUP BY已经减少了重复并且每组留下一行,即使我们现在加入了movie-&gt; recommended-&gt; cast
所以,现在我假设您希望在结果中的一列中使用强制转换。这里是GROUP_CONCAT实际上有用的地方,似乎是合适的:
SELECT tmdb_movies.movie_title, recommendations.recommendations_title, recommendations.recommendations_vote_average, GROUP_CONCAT(cast.name)
FROM tmdb_movies
LEFT JOIN recommendations ON recommendations.recommendations_tmdb_id=tmdb_movies.tmdb_id
LEFT JOIN cast ON cast.recommendations_title=recommendations.recommendations_title
GROUP BY tmdb_movies.tmdb_id, recommendations.recommendations_title