简体   繁体   中英

Many-to-Many with WHERE (PHP and MySQL)

I have a many-to-many table which is named with "users_groups". With this table I want to assign the unique user_id to a group_id. This works pretty well but now I want to make a panel which shows in which groups the current user is and what users are in these groups.

This is my current code for getting all groups with the users of them.

MySQL-Part

$all_groups = mysqli_query
            ($db, 
            "SELECT group_name,GROUP_CONCAT(realname SEPARATOR ', ') AS users
            FROM groups 
            JOIN users_groups ON groups.group_id=users_groups.group_id
            JOIN users ON users_groups.user_id=users.user_id
            GROUP BY group_name
            "
            );

PHP-Part

echo'
    <table class="table_standard">
        <tr>
            <th class="th_titlebar">Group</th>
            <th class="th_titlebar">Members</th>
        </tr>';
        while($row_all_groups = mysqli_fetch_array($all_groups)) {
            echo '<tr>';
                echo '<td class="td_contentbar">'.$row_all_groups["group_name"].'</td>';
                echo '<td class="td_contentbar">'.$row_all_groups["users"].'</td>';
            echo '</tr>';
        }
echo '</table>';

And now I have no idea how to include the WHERE-Part in the MySQL. I tried it already with WHERE users_groups.user_id = $session_user_id but with this method the member lists of the groups were just filled with the current user. My next idea was to make a first MySQL-Request like SELECT group_id FROM users_groups WHERE user_id=$user_id which safes the group_id's in an array and so on but this did not work for me, no idea why.

Are you trying to get it show what usergroup the current logged in user is in?

If so then this would be your sql based on the above:

SELECT group_name,GROUP_CONCAT(realname SEPARATOR ', ') AS users
FROM users 
JOIN users_groups ON users_groups.user_id = users.user_id
JOIN groups ON groups.group_id = users_groups.group_id
WHERE users.user_id = $session_user_id
GROUP BY groups.group_id

That should return a result with all the all the groups and the current user. To remove this repeating User if you was to just show the current groups the current user is assigned to then remove the realname part from the select and just have the group_name.

shows in which groups the current user is and what users are in these groups.

the groups the current user is in:

  SELECT g.group_name
    FROM groups g
    JOIN users_groups ug
      ON ug.group_id = g.group_id
   WHERE ug.user_id = :session_user_id
   ORDER BY g.group_name

To get a list of users that are in those groups , we need another join to the users_groups table. We can also add the join to the users table to get the information for those users...

  -- og = other user_id that are in a a group
  -- ou = info about those other users
  SELECT g.group_name
       , ou.user_id
       , ou.realname
    FROM groups g
    JOIN users_groups ug
      ON ug.group_id = g.group_id

    JOIN users_groups og
      ON og.group_id = g.group_id
    JOIN users ou
      ON ou.user_id = og.user_id

   WHERE ug.user_id = :session_user_id 
   ORDER BY g.group_name, ou.user_id

If you want to omit the current user from the list of users, you can add an inequality predicate.

If you want to collapse that to a single row for each group, you can use the GROUP BY clause and the GROUP_CONCAT function, as in your first query. For a more deterministic result, consider adding an ORDER BY in the GROUP_CONCAT. Beware of the group_concat_max_len setting, which limits the size of the string returned.

You can use a sub select and an additional join for your junction table to get only groups @session_user_id has an association and in GROUP_CONCAT part get all members from the resultant groups

SELECT g.group_name,GROUP_CONCAT(DISTINCT u.realname SEPARATOR ', ') AS users
  FROM groups g
  JOIN (SELECT * FROM users_groups WHERE user_id =@session_user_id) ug
     ON g.group_id=ug.group_id
  JOIN users_groups ug1 ON g.group_id=ug1.group_id
  JOIN users u ON ug1.user_id=u.user_id
GROUP BY g.group_name

DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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