简体   繁体   English

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

[英]Subqueries for each result or inner join with php loop or …?

I want to display in users search results also their photos. 我想在用户搜索结果中显示他们的照片。 Not only avatar photo but 3 photos. 不仅头像照片,而且3张照片。 Photos are in extra table user_photos. 照片在额外的表user_photos中。 If I would get single row per user the answer would be clear - inner join. 如果我每个用户得到单行,答案将很清楚-内部联接。 But I will get multirows for each user. 但是我将为每个用户获得多行。

First method I can use is join: 我可以使用的第一种方法是join:

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

In this case I need some extra php code to merge results with same user_id. 在这种情况下,我需要一些额外的PHP代码以将结果与相同的user_id合并。 Something like this: 像这样:

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'];
  //...
}

Then in view I need first first level loop for users and then for each user second level loop for $user[$result['user_id']]['photos'] array. 然后在视图中,我需要为用户提供第一级循环,然后为每个用户提供$ user [$ result ['user_id']] ['photos']数组的第二级循环。

or I can use for each result subquery. 或者我可以将其用于每个结果子查询。 None of options seems elegant, so I am wondering if there is any other way. 没有一个选项看起来很优雅,所以我想知道是否还有其他方法。 If not, probably first option is a way to go, correct? 如果没有,也许第一种选择是正确的吗?

For your original question, the first option is usually the way to go as it cuts down on the number of queries being sent to the database unnecessarily. 对于您的原始问题,第一个选择通常是解决方法,因为它减少了不必要地发送到数据库的查询数量。

However, I prefer Dows answer, which is almost there I think. 但是,我更喜欢Dows的答案,我认为差不多。 The one change I would make would be to make the join a LEFT JOIN so that users who have no photos are still returned in the query result, so on updating his query to: 我要进行的一项更改是使LEFT JOIN成为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;

Would return a result along the lines of: 将按照以下方式返回结果:

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

You want to use GROUP_CONCAT , so you will get something like this: 您要使用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;

Then you can simply use explode() to unpack the array. 然后,您可以简单地使用explode()解压缩数组。

The first option is the way to go, it is much more efficient than the second option, despite the fact that you are retrieving the user data more than once (it is returned for each matching image). 第一种选择是行之有效的方法,尽管您要检索用户数据不止一次(对于每个匹配的图像都会返回),但它比第二种方法效率更高。

The second option will be extremely inefficient as it gives the database much more work to do, as well as increasing the traffic between your script and the DB very heavily. 第二种方法效率极低,因为它使数据库要做的工作更多,并且极大地增加了脚本与数据库之间的通信量。

There is actually a 3rd option that I have previously shown can be implemented in situations like this, and that is to convert the photo information into a scalar value representing a vector that can be decoded in PHP using GROUP BY and GROUP_CONCAT() (I have used JSON for this in the past) but I can't say I would recommend it, although I will illustrate it if you would like me to. 实际上,我先前展示的第三个选项可以在这种情况下实现,即将照片信息转换为表示可以使用PHP使用GROUP BYGROUP_CONCAT()解码的矢量的标量值(我有过去曾为此使用JSON),但我不能说我会推荐它,尽管如果您愿意的话我会举例说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM