有没有办法在一次调用MySQL中从很多一对多表中提取数据?

时间:2017-02-03 18:50:34

标签: php mysql one-to-many

使用MySQL 5.7,我有一个movie表,其中包含许多单值字段:

+--------------+--------------+
| Field        | Type         |
+--------------+--------------+
| id           | int(11)      |
| title        | varchar(255) |
| release_year | int(11)      | 
| rating       | int(11)      |
+--------------+--------------+

当我在该表上调用查询时,如SELECT * FROM movie WHERE id = 5,它将按预期返回每列所有数据的一行。

我有许多表与movie表有一对多的关系。我有movie_subtitlemovie_languagemovie_actor等。例如,这里有一个:

+--------------+--------------+
| Field        | Type         |
+--------------+--------------+
| id           | int(11)      |
| movie_id     | int(11)      |
| subtitle     | varchar(255) | 
+--------------+--------------+

我的问题是,为了让我获得一部电影的所有现场数据,似乎我需要进行大约10次SELECT次电话。一个用于movie表,然后一个用于每个附加附加表。

如果用户有1,000部电影,如果我尝试针对整个集合运行更大的查询,则很快就会变成10,000 SELECT次电话。

有没有办法在一次电话中完成所有输出?或者这只是它应该的方式?我觉得有更好的方法可以做到这一点而且我对数据库关系的了解不足以了解我在这里缺少的东西。

我需要将从这些调用中收到的数据传递给我的PHP页面,将其放入JSON中。

1 个答案:

答案 0 :(得分:0)

我建议在php中进行多个查询并合并数据。以下是电影和流派的简单示例:

示例表:

Table: MOVIES
    id, title, release_year, rating ...etc

Table: MOVIES_GENRES (many-to-many relation to movies and genres)
    movie_id, genre_id

Table: GENRES
    id, name, description

Table: USERS_MOVIES (many-to-many relation to users and movies)
    user_id, movie_id

然后你可以这样做:

//example user id
$user_id = 5;

//query for all movies
$sql = "SELECT * FROM `movies` WHERE `id` IN (SELECT `movie_id` FROM `users_movies` WHERE `user_id`={$user_id})";

$result = /*perform query*/;

//loop over the result
$movies = array();
while($row = $result->fetch(PDO::FETCH_ASSOC)){
    //add the row to the movies array with the movie id as the key
    $movies[$row['ID']] = $row;

    //also add an empty genre array in anticipation of genre data being coalesced
    $movies['genres'] = array();
}

//get a comma separated list of all the movie ids for use in queries below
$movieIDs = implode(',', array_keys($movies));

//now query out genre based on movies, make sure to get the movie_id for coalesce
$sql = "SELECT `movie_id`, `name`, `description` FROM `genres` JOIN `movies_genres` ON `genre_id`=`genres`.`id` WHERE `movie_id` IN ({$movieIDs})";

$result = /*perform query*/;

//loop over the result
while($row = $result->fetch(PDO::FETCH_ASSOC)){
    //add the genre to this movie
    $movies[$row['movie_id']]['genres'][] = $row;
}

在整个事情中,无论有多少电影,我都只使用两个查询。我只是生成所有电影ID的列表,并在后续查询中使用它。然后在php中将数据合并在一起。在后面的行中,我可以遍历$movies数组并使用它来构建表或我需要的任何内容。在流派查询中,您还可以在users_movies上添加movie_id的加入(或子查询),然后不需要大IN列表,但可以使用来自上面的user_id。