[英]How can I show rows from one table that aren't in another table?
I have two tables in a database, one of them is a list of 'buildings' you could create. 我在数据库中有两个表,其中一个是可以创建的“建筑物”列表。 The other is a list of buildings that have been built by users.
另一个是用户建造的建筑物的列表。
On one page, (cityproduction.php), it displays a list of 'buildings' you can build. 在一个页面上(cityproduction.php),它显示了您可以建造的“建筑物”列表。 I want it to display the buildings that you can build, that you haven't already built.
我希望它显示您尚未建造的建筑物。
Here is my code: 这是我的代码:
$sql = "SELECT * FROM [The list of built buildings] WHERE building_owner = '$user'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$variable = $row["building_name"];
}
(...) (...)
$sql = "SELECT * FROM [The list of ALL buildings] WHERE name != '$variable' ORDER BY id asc";
$result = mysqli_query($database,$sql) or die(mysqli_error($database));
while($rws = mysqli_fetch_array($result)){
echo $rws["name"]; (etc.)
What this is doing is only not-showing one of the buildings that the user has built, not all of them. 这只是在不显示用户已建造的建筑物之一,而不是全部。
Without seeing the real table names or the schema it is tricky to answer accurately but you could try something along these lines: 没有看到真实的表名或模式,很难准确地回答,但是您可以尝试以下方法:
SELECT * FROM `all_buildings`
WHERE `id` not in (
select `building_id` from `built_buildings` where `building_owner` = '$user'
)
ORDER BY `id` asc;
Another translation of your question into SQL (besides NOT IN
) results in a Correlated Subquery: 将问题转换为SQL的另一种方式(除
NOT IN
之外)将导致相关子查询:
SELECT * FROM `all_buildings` AS a
WHERE NOT EXISTS
(
select * from `built_buildings` AS b
where a.`id` = b.`building_id` -- Outer Select correlated to Inner
and b.`building_owner` = '$user'
)
ORDER BY `id` asc;
The main advantage over NOT IN
: it's using only two-valued-logic ( NULL
is ignored = false) while NOT IN
uses three-valued-logic (comparison to NULL returns unknown which might no return what you expect) 相对于
NOT IN
的主要优势:它仅使用二值逻辑(忽略NULL
= false),而NOT IN
使用三值逻辑(与NULL比较将返回未知值 ,可能不会返回您期望的值)
Why are you using while
after the first query, it suppose to be a list or just a single value? 为什么在第一个查询之后使用
while
,假设它是一个列表或只是一个值? because if you use $variable
in your second query it will only have the value of the last value of the list you are getting 因为如果您在第二个查询中使用
$variable
,它将仅具有您要获取的列表的最后一个值的值
if ($result->num_rows > 0) {
$variable = array();
while($row = $result->fetch_assoc()) {
$variable[] = $row["building_name"];
}
Second query example: 第二个查询示例:
foreach($variable as $building) {
$sql = "SELECT * FROM [The list of ALL buildings] WHERE name != '$building' ORDER BY id asc";
$result = mysqli_query($database,$sql) or die(mysqli_error($database));
$result = mysqli_fetch_assoc($result);
echo $result["name"];
}
Assuming both of your tables have some sort of id column to relate them, with this query: 假设您的两个表都有某种ID列来关联它们,并使用以下查询:
SELECT building_name, building_owner FROM
test.all_buildings a
LEFT JOIN test.built_buildings b ON a.id = b.building_id AND b.building_owner = ?
ORDER BY building_owner DESC, building_name;
(where ?
is the user), you can select all the buildings, first the ones that have been built, followed by the ones that haven't, in one query. (其中
?
是用户),您可以在一个查询中选择所有建筑物,首先选择已建造的建筑物,然后选择尚未建造的建筑物。 If your tables don't have id's like that, you can join them on name instead; 如果您的表没有这样的ID,则可以按名称加入它们; it should work as long as the names are distinct.
只要名称不同,它就应该起作用。
Then as you fetch the rows, you can sort them into "built" or "not built" by checking if the row has a building_owner
. 然后,当您获取行时,可以通过检查行是否具有
building_owner
,将它们分为“内置”或“非内置”。
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
if ($row['building_owner']) {
$built[] = $row['building_name'];
} else {
$not_built = $row['building_name'];
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.