MySQL 加入两个表,给出 table 1 的所有条目

MySQL Join two Tables, give all entries of table 1

我有三张表。

Table 1: tbl_user

id username
1 User A
2 User B

Table 2: tbl_location

id location
1 City 1
2 City 2
3 City 3

Table 3: tbl_user位置

fk_user fl_location
1 1
2 1
2 2

现在我有一个 HTML 页面来编辑用户数据

我有两个问题。一种用于读取用户数据,另一种用于位置。

public function readOneUser($id)
{
    $stmt = $this->pdo->prepare("SELECT * FROM tbl_user WHERE id = :id");
    $stmt->execute([
        'id' => $id
    ]);
    $stmt->setFetchMode(PDO::FETCH_CLASS, "administration\CMR\UserModel");
    $res = $stmt->fetch(PDO::FETCH_CLASS);
    return $res;
}

没关系。一切都很好。我有普通的用户数据,如用户名、邮件、phone...

现在我想要所有位置的完整列表,但是(这就是问题所在)应该检查分配给用户的所有位置。未分配用户的位置不应选中,而应列出。

<?php
    foreach ($readLocations AS $location):
    ?>
    <input type="checkbox" name="location" <?= htmlspecialchars($location->id == $location->fk_location) ? "checked" : "" ?> value="<?= $location->id; ?>"><span><?= $location->location; ?></span><br>
    <?php
    endforeach;
?>

我有这个问题。我知道这是错误的,但那是我拥有的“最好的”。希望你能帮我改正。

public function readAllLocationsForEdit($id)
{
    $stmt = $this->pdo->prepare("
        SELECT tbl_location.*, tbl_userlocation.*
        FROM tbl_location
        LEFT JOIN tbl_userlocation ON tbl_userlocation.fk_location = tbl_location.id 
        WHERE fk_user = :id
        GROUP BY location");
    $stmt->execute([
        'id' => $id
    ]);
    $res = $stmt->fetchAll(PDO::FETCH_CLASS, "administration\CMR\LocationModel");
    return $res;
}

有了这个,我得到了分配给用户的所有位置,但没有分配给用户的位置。我知道,WHERE 子句不正确,但我测试的所有其他子句都没有给我想要的结果。

WHERE 子句在 JOIN.

之后应用

根据您的需要,您需要在之前期间过滤用户位置图加入。要么在连接谓词中包含用户过滤器,要么连接过滤用户 的 sub-query(前者是通常的、更简洁的方法).

     FROM tbl_location
LEFT JOIN tbl_userlocation
       ON tbl_userlocation.fk_location = tbl_location.id 
      AND tbl_userlocation.fk_user     = :id

或者...

     FROM tbl_location
LEFT JOIN (SELECT * FROM tbl_userlocation WHERE fk_user = :id) AS tbl_userlocation 
       ON tbl_userlocation.fk_location = tbl_location.id