Sql 带where条件的外连接

Sql 带where条件的外连接,sql,database,ms-access,database-design,Sql,Database,Ms Access,Database Design,我正在尝试获取所有可用的密钥,这意味着已返回的密钥(返回日期不为null)、未丢失的密钥(丢失的密钥=false)以及以前从未租用过的密钥(id为null)。但是,当我运行此命令时,得到0个recirds。如果我删除id条件,我只会得到以前租用过的密钥,并且忽略不在keyActivity表中的所有密钥。有人知道我做错了什么吗 SELECT a.key_id, a.drawer_num FROM keys AS a left outer JOIN keyActivity AS

我正在尝试获取所有可用的密钥,这意味着已返回的密钥(返回日期不为null)、未丢失的密钥(丢失的密钥=false)以及以前从未租用过的密钥(id为null)。但是,当我运行此命令时,得到0个recirds。如果我删除id条件,我只会得到以前租用过的密钥,并且忽略不在keyActivity表中的所有密钥。有人知道我做错了什么吗

SELECT a.key_id, a.drawer_num
FROM 
    keys AS a 
    left outer JOIN keyActivity AS b 
        ON a.key_id = b.key_id
WHERE 
    return_date is not null 
    and lost_key =false
    and id is null;

使用的解决方案:

SELECT a.key_id, a.drawer_num
FROM keys AS a LEFT JOIN keyActivity AS b ON a.key_id = b.key_id
WHERE (b.return_date is not null 
and b.lost_key =false) 
OR b.id is null;

id
可能是两个表中的一个字段,如果是这样,您的条件
id为null
将被错误地解释为
键的
id
null
,从而导致结果集为空

如果您按其全名调用它,即
b.id
,它应该可以工作,因为您希望排除任何以前的
keyActivity

但是,我也相信您希望前面的两个条件都通过
和括号连接,然后最后一个条件通过
连接,因为只要返回了密钥,前面的密钥活动就可以了

SELECT * FROM keys AS a LEFT OUTER JOIN keyActivity AS b ON a.key_id = b.key_id
  WHERE (b.return_date IS NOT NULL OR b.id IS NULL) AND a.lost_key = false;

编辑:我重新安排了条件,以发现职员在分发钥匙之前丢失钥匙的情况。

一张桌子有钥匙id,另一张桌子有id,所以这不是问题所在。你写的是OR和括号。成功了。谢谢。活动表中的lost_key属性,因此按照您的方式重新排列会导致错误。另一个线程的人建议我的密钥表也有一个丢失选项。有什么想法吗?啊哈,如果是这样的话,你可以简单地恢复到我们以前的状态(使用
b.lost_key
),因为在那种型号中,店员不能丢失钥匙。你在别处听到的建议对我来说很有意义;这是我凭直觉所想的。如果你想遵循这个建议,那么经过编辑的查询将是适合你的查询。我想我现在就不做了。我觉得把它放在活动表中可以提供关于哪个用户丢失了密钥以及他们注销日期的信息。如果一个职员丢失了钥匙,他们可以用一张表格把它删除(我以后再做)。这有意义吗?我认为这是特定于RDBMS的,与SQL无关。很抱歉,我必须传递这个。我已经尝试了很多次选择和取消选择丢失属性。从我所看到的情况来看,这个查询似乎正确地捕捉到了可用的键。我已经使用查询编辑了OP。