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
我有三张表。
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