使用连接并将连接结果放入数组中?

时间:2016-11-18 10:26:48

标签: php mysql

我有一个用户和一个帖子表:

用户

id | name

帖子

id | post | user_id (fk)

我想让所有用户获得他们的帖子:

SELECT users.name, posts.post FROM users LEFT JOIN posts ON user.id posts.user_id

从上面的查询中,我得到每个帖子的重复用户信息的单独结果,例如

name | post
john | about me...
john | about my pets
....

我正在寻找一个结构,我将所有帖子组合在一起,所以在PHP中我可以循环遍历数组,如:

[0]=> array(2) { ["name"]=> string(4) "john" ["posts"]=> array(22){....}

3 个答案:

答案 0 :(得分:0)

将它放入php中的数组的粗略方式: -

$sql = "SELECT users.name, posts.post 
        FROM users 
        LEFT JOIN posts 
        ON user.id posts.user_id 
        ORDER BY users.name, posts.post";

$db->query($sql) or die($db->error());

$out_array = array();

while($row_item = $db->fetch_assoc())
{
    $out_array[$row_item['name']][] = $row_item['post'];
}

使用GROUP_CONCAT你可以执行以下操作,但它受限于用户的帖子输出大小,并没有真正修复任何内容(如果任何帖子包含分隔字符串,则会出现问题,在这种情况下# 〜#)。

$sql = "SET SESSION group_concat_max_len = 1000000;

$db->query($sql) or die($db->error());

$sql = "SELECT users.name, GROUP_CONCAT(posts.post SEPARATOR '#~#') AS out_post
        FROM users 
        LEFT JOIN posts 
        ON user.id posts.user_id 
        GROUP BY users.name
        ORDER BY users.name";

$db->query($sql) or die($db->error());

$out_array = array();

while($row_item = $db->fetch_assoc())
{
    $out_array[$row_item['name']] = explode('#~#', $row_item['out_post']);
}

如果你真的想要,可以使用上面的变体来手动建立帖子数组作为php序列化数组。我以前做过这个,但只是在特殊情况下(并且有一个字符串数组使得避免错误变得更加困难)。我肯定不会推荐那些以传统方式轻松应对的东西。

修改

很无聊所以打倒了。这更多的是向您展示返回序列化数组而不是使用严格的代码是多么可怕。维护可能是一场噩梦,执行起来可能非常慢,如果不存在无法提供有效序列化数组的情况,我会感到惊讶。请注意,在使用它之前,您需要将max group concat length设置为愚蠢(例如, SET SESSION group_concat_max_len = 1000000; 甚至sillier)。

SELECT CONCAT('a:', COALESCE(COUNT(sub2.name), 0), ':{', GROUP_CONCAT(user_posts SEPARATOR ''), '}')
FROM
(
    SELECT  users.name,
            CONCAT('s:', LENGTH(users.name), ':"', users.name, '";a:', COALESCE(COUNT(sub1.user_id), 0), ':{', COALESCE(GROUP_CONCAT(all_fields ORDER BY counter SEPARATOR ''), ''), '}') AS user_posts
    FROM users
    LEFT OUTER JOIN
    (
        SELECT user_id, 
                @cnt:=if(@prev_id != user_id, 0, @cnt + 1) AS counter,
                CONCAT('i:', @cnt, ';s:',LENGTH(post),':"', post, '";') AS all_fields,
                @prev_id := user_id
        FROM posts
        CROSS JOIN (SELECT @cnt:=0, @prev_id:=0) sub99
    ) sub1
    ON sub1.user_id = users.id
    GROUP BY users.name
) sub2

答案 1 :(得分:0)

$result=mysql_query("SELECT users.id,users.name, posts.post FROM users LEFT JOIN posts ON user.id posts.user_id");
$responce=array();
while($row=mysql_fetch_assoc($result)){
$responce[$row['id']]['name']=$row['name'];
$responce[$row['id']]['posts'][]=$row['name'];
}
foreach($responce as $array){
$data[]=$array;
}
echo json_encode($data);

答案 2 :(得分:0)

I hope this gives you idea to do what you want. Just polish it up and you will be good. I did that once with a project i was working on

$usersPostsArray = array(); // Multi dimensional array to store the users and their posts
$usersQuery = "select distinct name from users";
$result = mysqli_query($mysqli,$usersQuery);
//First loop through the users
while ($row = mysqli_fetch_assoc($result)){
    $postsQuery = "select * from posts where user_id = $row[id]"; // Select based on the user
    $postresult = mysqli_query($mysqli,$postsQuery);
    //Then loop through the posts based on the user
    while ($postrow = mysqli_fetch_assoc($postresult)){
        array_push($usersPostsArray, $row['name'], $postrow['post']); 
    }

}

// Manipulate your array to get what you want