如何在一个表中显示不在另一个表中的行?

时间:2016-08-19 15:52:56

标签: php sql

我在数据库中有两个表,其中一个表是一个'建筑物的列表。你可以创造。另一个是用户建造的建筑物清单。

在一页(cityproduction.php)上,它显示了一个'建筑物的列表。你可以建立。 我希望它能够显示您可以构建的建筑物,而这些建筑物尚未建成。

这是我的代码:

$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.)

这样做只是没有显示用户构建的建筑物之一,而不是所有建筑物。

4 个答案:

答案 0 :(得分:1)

如果没有看到真正的表名或模式,那么准确回答是很棘手的,但你可以尝试这些方法:

SELECT * FROM `all_buildings` 
WHERE `id` not in ( 
    select `building_id` from `built_buildings` where `building_owner` = '$user'
    ) 
ORDER BY `id` asc;

答案 1 :(得分:1)

将您的问题转换为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;

优于NOT IN的主要优点:它仅使用二值逻辑(NULL被忽略= false)而NOT IN使用三值逻辑(与NULL返回比较< em> unknown ,可能无法返回您的预期)

答案 2 :(得分:0)

为什么在第一次查询后使用while,它会是一个列表还是只是一个值?因为如果你在第二个查询中使用$variable,它只会得到你所获得的列表的最后一个值的值

if ($result->num_rows > 0) {

  $variable =  array();

  while($row = $result->fetch_assoc()) {

    $variable[] = $row["building_name"];    
}

第二个查询示例:

 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"];
    }

答案 3 :(得分:0)

假设您的两个表都有某种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;

(其中?是用户),您可以在一个查询中选择所有建筑物,首先是已建造的建筑物,然后是那些没有建筑物的建筑物。如果您的桌子没有这样的ID,您可以将其加入名称中;只要名称不同,它就应该有效。

然后,当您获取行时,您可以将它们排序为&#34;内置&#34;或者&#34;没有建造&#34;通过检查该行是否有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'];
        }
    }
}