如何在不依赖PHP循环的情况下执行此查询?

时间:2013-06-04 22:38:19

标签: php mysql loops for-loop inner-join

我是MySQL的新手。看起来我需要在MySQL请求中进行某种循环,但我认为使用一些“INNER JOIN”可能会更有效。

这是我的PHP代码:

$query = 'SELECT id FROM membres WHERE pseudo = :pseudo LIMIT 1';
$req = $dtb -> prepare($query);
$req -> execute(array(
    'pseudo' => $_COOKIE['pseudo']
));
while($donnes = $req -> fetch()){
    $id_pseudo = $donnes['id'];
}
$req -> closeCursor();
$query = 'SELECT id_chanson FROM samples WHERE id_membre = :id_pseudo';
$req = $dtb -> prepare($query);
$req -> execute(array(
    'id_pseudo' => $id_pseudo
));
$id_chansons = array();
while($donnes = $req -> fetch()){
    $id_chansons[] = $donnes['id_chanson'];
}
$req->closeCursor();
$nSongs= count($id_chansons);
$query = 'SELECT nom, pathName, date FROM chansons WHERE id = :id_chanson';
$req = $dtb -> prepare($query);
for($i=0;$i<$nSongs;$i++){
    $req -> execute(array(
        'id_chanson' => $id_chansons[$i]
    ));
    while($donnes = $req -> fetch()){
        $nomChanson[$i] = $donnes['nom'];
        $pathName[$i] = $donnes['pathName'];
        $date[$i] = $donnes['date'];
    }
}

编辑:我的表名是“chansons”(法语歌曲)“membres”(用户)和“样本”

:)

2 个答案:

答案 0 :(得分:0)

select m.id, s.id_chanson, ch.nom, ch.pathName, ch.date
  from membres m
       inner join samples s on m.id = s.id_membre
       inner join chansons ch on s.id_chanson = ch.id
 where pseudo = :pseudo

答案 1 :(得分:0)

你是对的,运行单个查询而不是多个查询通常效率更高。它在数据库上的速度更快(往返次数更少),并且可以提供更友好的代码。

以下是一个示例SQL查询,它将从chansons中检索行:

    SELECT c.nom
         , c.pathName
         , c.date
      FROM (SELECT id FROM membres WHERE pseudo = :pseudo ORDER BY id LIMIT 1) m
      JOIN samples s 
        ON s.id_membre = m.id
      JOIN chansons c
        ON c.id = s.id_chanson
     ORDER BY 1

注意:

如果需要结果集中返回的其他表中的id值,那么这些表的表达式也可以包含在SELECT列表中。 (从您的代码中,我没有看到那些id值被用于除后续查询之外的任何内容......但当然这并不意味着它们在其他地方没有被引用。

我在内联视图中为查询添加了ORDER BY,以使其具有确定性。如果满足查询的行不止一行,则缺少ORDER BY子句,MySQL将返回哪个行,即后续执行返回的结果不保证与前一次运行相同。)

上面的查询使用内联视图(MySQL将其称为派生表)别名为m,以获得LIMIT 1membres返回的行数。如果您不需要LIMIT,则可以通过删除内联视图来简化查询。

INNER关键字是可选的,它对优化器没有影响。也就是说,INNER JOINJOIN同义。