访问2010查询混淆

时间:2012-06-27 15:32:51

标签: sql ms-access

只需要一些快速澄清

我的Access数据库中有两个应该返回Inverse结果的查询:

SELECT Equipment.title
FROM Equipment
WHERE (((Equipment.[EquipmentID]) Not In (

    select EquipmentID
    from DownPeriod
    where UpDate is null
)));

第二个排除了In之前的Not。 我的困惑来自以下事实:如果EquipmentID字段在DownPeriod表中至少有1个空值,则上面发布的查询不会返回任何结果。

如果字段已填充,则工作正常,反向查询列表始终有效。这让我觉得null值存在问题。

现在这个字段永远不应该为null但是我想知道我是否还能在不太可能发生null的情况下使用它。

先谢谢你了!

2 个答案:

答案 0 :(得分:4)

尝试加入:

SELECT Equipment.title FROM Equipment INNER JOIN DownPeriod
ON Equipment.EquipmentID = DownPeriod.EquipmentID
WHERE DownPeriod.UpDate is null

SELECT Equipment.title FROM Equipment INNER JOIN DownPeriod
ON Equipment.EquipmentID = DownPeriod.EquipmentID
WHERE DownPeriod.UpDate is not null

查看语法更改是否可以解决您的问题。

这不仅应该起作用,而且我认为这比使用IN() NOT IN()方法更快(可能是错误的,但看起来更好看)。它还增加了快速更改“非空”标准的能力,与IN-> NOT IN

相同

答案 1 :(得分:3)

我同意StuckAtWork的做法。但是,如果您仍然想了解为什么您的原始方法无法产生您想要的结果,我想我可以帮助您。

空字符串可能存在问题,这可能会使情况复杂化。但无论是否涉及空字符串,您都需要考虑更基本的内容。

这是我的Equipment表格版本。

EquipmentID title
1           one
2           two
3           three

这是我DownPeriod表的版本。

ID EquipmentID text_field
1  1           one
2  2           two
3              Null
4  3           three

我没有在UpDate表中添加您的DownPeriod字段。这与你的问题无关。

我将您的SQL粘贴到一个新的Access查询中,从子查询中丢弃了WHERE子句,并得到了与此查询完全相同的结果---没有返回任何行:

SELECT e.title
FROM Equipment AS e
WHERE
    e.EquipmentID Not In (
        SELECT EquipmentID
        FROM DownPeriod
        );

从数据库引擎的角度考虑这种情况。使用我的Downloads表版本,它有一组来自子查询的值(1,2,Null和3)。您要求它显示Equipment的行EquipmentID NOT IN 的值列表。 db引擎只会为您提供该条件为True的行。

Null是问题所在。对于每个EquipmentID,当它考虑子查询集中是否存在 not 时,它不知道。 Null是一个未知值......未知值可能与它正在考虑的当前EquipmentID相同......或者可能是其他值。但由于db引擎不知道实际值,因此无法将条件评估为True,因此不会在结果集中包含该行。 Equipment表中的每一行都会发生同样的事情...因此查询的结果集为空(无行)。

您可以通过使用Null子句从子查询结果集中排除WHERE值来获得所需的结果,如下所示。但我认为StuckAtWork的建议是一个更好的方法。

SELECT e.title
FROM Equipment AS e
WHERE
    e.EquipmentID Not In (
        SELECT EquipmentID
        FROM DownPeriod
        WHERE EquipmentID Is Not Null
        );