多对多没有结果
Many-to-Many gives no result
起初我的多对多关系是与以下 tables:
+----------+ +--------------+
| users | | users_groups | +--------------+
+----------+ +--------------+ | groups |
| user_id |----->| user_id | +--------------+
| username | | group_id |<----| group_id |
| realname | +--------------+ | group_name |
| password | | group_desc |
+----------+ +--------------+
现在我想获得所有现有组的 list/table(不是数据库中的 table!)以及特定组的所有用户,如下所示:
+---------------+--------------------------+
| group | members |
+---------------+--------------------------+
| Group1 | User1, User2, User3 |
| Group2 | User3, User4, User6 |
| Group3 | |
+---------------+--------------------------+
我当前的MySQL代码是:
$all_groups = mysqli_query
($db,
"
SELECT g.group_name,GROUP_CONCAT(DISTINCT u.realname SEPARATOR ', ') AS users
FROM groups g
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
"
);
我当前的PHP-代码是:
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>';
}
但问题是 如果一个组没有用户(在 users_groups-table 中),则该组不会显示在 list/table 我有 和我不知道如何解决这个问题。
将 JOIN users_groups
替换为 LEFT JOIN users_groups
无效。
你只需要 left join
:
SELECT g.group_name,
GROUP_CONCAT(DISTINCT u.realname SEPARATOR ', ') AS users
FROM groups g LEFT JOIN
users_groups ug1
ON g.group_id = ug1.group_id LEFT JOIN
users u ON ug1.user_id = u.user_id
GROUP BY g.group_name;
当使用 LEFT JOIN
时,通常将 table 与要保留的行放在首位。然后对所有后续联接使用 LEFT JOIN
。
此外,您的数据可能在组中没有重复的用户名。 DISTINCT
关键字会影响性能,应仅在需要时使用。
我不会在 PHP 中编程,但我可以给你另一种方法来解决这个问题。 (将用 C# 逻辑编写)
首先带来一个 table 将所有组与用户相关联(使用左关节来带来没有用户的偶数组)
SELECT g.group_name, u.realname AS users
FROM groups g
LEFT JOIN users_groups ug1 ON g.group_id=ug1.group_id
JOIN users u ON ug1.user_id=u.user_id
然后在 PHP
中这样做
$TEMP_VAR_LAST_GROUP = "NOGROUPNAMEATALL";
$I_HAVE_DATA = "FALSE";
while($row_all_groups = mysqli_fetch_array($all_groups)) {
$I_HAVE_DATA = "TRUE";
if($TEMP_VAR_LAST_GROUP != "NOGROUPNAMEATALL")
{
// This is just to close the tags after the last loop
echo '</td></tr>'
}
If ($TEMP_VAR_LAST_GROUP == $row_all_groups["group_name"])
{
// this is a new group
echo '<tr>';
echo '<td class="td_contentbar">'.$row_all_groups["group_name"].'</td>';
echo '<td class="td_contentbar">'.$row_all_groups["users"].'
}
else
{
// this is the same group, but new user
echo ','.$row_all_groups["users"].'
}
// SETS A NEW LASST GROUP VAR
$TEMP_VAR_LAST_GROUP == $row_all_groups["group_name"])
}
// This will close the last tags if the table has data
if($I_HAVE_DATA = "TRUE")
{
echo '</td></tr>'
}
起初我的多对多关系是与以下 tables:
+----------+ +--------------+
| users | | users_groups | +--------------+
+----------+ +--------------+ | groups |
| user_id |----->| user_id | +--------------+
| username | | group_id |<----| group_id |
| realname | +--------------+ | group_name |
| password | | group_desc |
+----------+ +--------------+
现在我想获得所有现有组的 list/table(不是数据库中的 table!)以及特定组的所有用户,如下所示:
+---------------+--------------------------+
| group | members |
+---------------+--------------------------+
| Group1 | User1, User2, User3 |
| Group2 | User3, User4, User6 |
| Group3 | |
+---------------+--------------------------+
我当前的MySQL代码是:
$all_groups = mysqli_query
($db,
"
SELECT g.group_name,GROUP_CONCAT(DISTINCT u.realname SEPARATOR ', ') AS users
FROM groups g
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
"
);
我当前的PHP-代码是:
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>';
}
但问题是 如果一个组没有用户(在 users_groups-table 中),则该组不会显示在 list/table 我有 和我不知道如何解决这个问题。
将 JOIN users_groups
替换为 LEFT JOIN users_groups
无效。
你只需要 left join
:
SELECT g.group_name,
GROUP_CONCAT(DISTINCT u.realname SEPARATOR ', ') AS users
FROM groups g LEFT JOIN
users_groups ug1
ON g.group_id = ug1.group_id LEFT JOIN
users u ON ug1.user_id = u.user_id
GROUP BY g.group_name;
当使用 LEFT JOIN
时,通常将 table 与要保留的行放在首位。然后对所有后续联接使用 LEFT JOIN
。
此外,您的数据可能在组中没有重复的用户名。 DISTINCT
关键字会影响性能,应仅在需要时使用。
我不会在 PHP 中编程,但我可以给你另一种方法来解决这个问题。 (将用 C# 逻辑编写)
首先带来一个 table 将所有组与用户相关联(使用左关节来带来没有用户的偶数组)
SELECT g.group_name, u.realname AS users
FROM groups g
LEFT JOIN users_groups ug1 ON g.group_id=ug1.group_id
JOIN users u ON ug1.user_id=u.user_id
然后在 PHP
中这样做$TEMP_VAR_LAST_GROUP = "NOGROUPNAMEATALL";
$I_HAVE_DATA = "FALSE";
while($row_all_groups = mysqli_fetch_array($all_groups)) {
$I_HAVE_DATA = "TRUE";
if($TEMP_VAR_LAST_GROUP != "NOGROUPNAMEATALL")
{
// This is just to close the tags after the last loop
echo '</td></tr>'
}
If ($TEMP_VAR_LAST_GROUP == $row_all_groups["group_name"])
{
// this is a new group
echo '<tr>';
echo '<td class="td_contentbar">'.$row_all_groups["group_name"].'</td>';
echo '<td class="td_contentbar">'.$row_all_groups["users"].'
}
else
{
// this is the same group, but new user
echo ','.$row_all_groups["users"].'
}
// SETS A NEW LASST GROUP VAR
$TEMP_VAR_LAST_GROUP == $row_all_groups["group_name"])
}
// This will close the last tags if the table has data
if($I_HAVE_DATA = "TRUE")
{
echo '</td></tr>'
}