使用php循环或......的每个结果或内部联接的子查询?

时间:2012-07-12 08:13:19

标签: php mysql subquery inner-join

我想在用户搜索结果中显示他们的照片。不仅是头像照片而是3张照片。照片在额外的表user_photos中。如果我为每个用户获得单行,答案就会很明确 - 内部联接。但我会为每个用户获得多行。

我可以使用的第一种方法是加入:

SELECT * FROM users INNER JOIN photos ON photos.user_id=users.user_id

在这种情况下,我需要一些额外的PHP代码来将结果与同一个user_id合并。像这样:

foreach($results as $result){
  if(isset($user[$result['user_id']]['age'])){
    $user[$result['user_id']]['photos'][] = $result['photo'];
    continue;
  }      
  $user[$result['user_id']]['age'] = $result['age'];
  $user[$result['user_id']]['photos'][] = $result['photo'];
  //...
}

然后在视图中我需要为用户首先进行第一级循环,然后为$ user [$ result ['user_id']] ['photos']数组的每个用户第二级循环。

或者我可以用于每个结果子查询。没有任何选项看起来很优雅,所以我想知道是否还有其他方法。如果没有,可能第一种选择是一种方法,对吗?

3 个答案:

答案 0 :(得分:2)

对于您的原始问题,第一个选项通常是可行的方法,因为它会减少不必要地发送到数据库的查询数量。

然而,我更喜欢Dows的答案,这几乎就在我想到的地方。我要进行的一项更改是将联接设置为LEFT JOIN,以便在查询结果中仍然返回没有照片的用户,以便将查询更新为:

select u.*, group_concat(photos.name SEPARATOR ' & ') as name
from users u
     join photos on photos.user_id=u.user_id
group by u.user_id;

将返回以下行的结果:

+-------------------------------------+
|user_id   |photo                     |
+----------+--------------------------+
|1         |photo1 & photo2 & photo7  |
+----------+--------------------------+
|2         |                      NULL|
+----------+--------------------------+
|3         |photo3 & photo5           |
+-------------------------------------+

答案 1 :(得分:1)

你想使用GROUP_CONCAT,所以你会得到这样的东西:

select u.*, group_concat(photos.name SEPARATOR ' & ') as photonames
from users u
     join photos on photos.user_id=users.user_id
group by a.user_id;

然后您只需使用explode()解压缩数组。

答案 2 :(得分:1)

第一个选项是要走的路,它比第二个选项更有效率,尽管您要多次检索用户数据(每个匹配的图像都会返回)。

第二个选项效率极低,因为它为数据库提供了更多的工作,并且非常大量地增加了脚本和数据库之间的流量。

实际上有一个第三个选项,我之前已经在这样的情况下实现可以,这就是将照片信息转换为表示可以在PHP中解码的向量的标量值使用GROUP BYGROUP_CONCAT()(我过去曾使用JSON),但我不能说我会推荐它,但如果你愿意,我会说明一下。