从多行的关系表中获取数据

时间:2016-04-28 14:08:54

标签: php mysql database

我有这张表:

博客

id
name
user_id // author - relational to "users"

用户

id
nickname
avatar

suscriptions

id
blog_id // relational to "blogs"
user_id // relational to "users"

这个想法是在网站上显示如下内容:

Blogname
Created By Stack
Suscriptions: Overflow, Easy, Robinson, Porter

我从blogs

获取所有数据
SELECT
    b.id,
    b.name,
    b.user_id,
    u.nickname as user_nickname,
    u.avatar as user_avatar
FROM blogs b
LEFT JOIN users u ON b.user_id = u.id

使用PHP我创建了一个包含所有blogs ID的数组,因此我可以将它们与IN运算符一起使用,如下所示:

SELECT
    s.id,
    s.blog_id,
    u.nickname,
    u.avatar
FROM suscriptions s
LEFT JOIN users u ON s.user_id = u.id
WHERE s.blog_id IN (1, 2, 3)

然后PHP再次对结果进行排序。

但是,有更好的方法吗?我只考虑使用MySQL而不是PHP。也许只在一个查询中获取所有数据?或者最好的方法是什么?

重要的是要记住,blog可以有多个subscriptions

我发现2012年的这个问题有点类似:JOIN three tables and aggregate data from multiple rows for every DISTINCT row in separate column 但OP表示它真的很慢,所以我现在有点迷失。

2 个答案:

答案 0 :(得分:1)

我认为你需要的是对'join suscriptions'生成的所有行进行分组,并将它们用逗号连接起来进行演示。

SELECT
    b.id AS blog_id,
    b.name AS blog_name,
    u.nickname AS user_create_nickname,
    u.avatar AS user_create_avatar,
    GROUP_CONCAT(us.nickname SEPARATOR ', ') AS users_suscritions
FROM blogs b
INNER JOIN users u ON b.user_id = u.id
LEFT JOIN suscriptions s ON s.blog_id = b.id
LEFT JOIN users us ON s.user_id = us.id
GROUP BY b.id;

答案 1 :(得分:0)

你可以做两个中的任何一个。几个小查询或一个带有更多连接或(甚至是子查询)的大查询,以便一次获取所有数据。在获得大量数据之前,您不会注意到任何一种情况下的性能差异。

如果您刚开始使用PHP,我建议您坚持使用更易于调试和理解的小型查询。毕竟MySQL可以很好地进行小型快速查询。

很快,您转移到ORM(或框架),将为您编写查询。您只需要关注您尝试解决的问题的逻辑。

例如在CakePHP中你只需要这样做:

$blogs = $this->Blog->find('all')

鉴于Blog属于UserUser可以有多个Subscriptions,所有数据都将“自动”检索(它会生成连接表的SQL本身就像Doglas's answer中的那个。

所以现在,我建议专注于构建易于理解调试优化小查询 维护

这是a list of ORMs in PHP。这些很常见:

    来自Eloquent小组的
  1. Laravel
  2. Propel
  3. here is来自同一博客的关于ORM的帖子;)