我想在用户搜索结果中显示他们的照片。不仅是头像照片而是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']数组的每个用户第二级循环。
或者我可以用于每个结果子查询。没有任何选项看起来很优雅,所以我想知道是否还有其他方法。如果没有,可能第一种选择是一种方法,对吗?
答案 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 BY
和GROUP_CONCAT()
(我过去曾使用JSON),但我不能说我会推荐它,但如果你愿意,我会说明一下。