【问题标题】:How to return all records only if join in SELECT returns null set仅当 SELECT 中的联接返回空集时如何返回所有记录
【发布时间】:2017-01-08 08:26:35
【问题描述】:

我在表单中有一个列表框,该列表框由基于同一表单中另一个控件 (ctrl1) 的选择查询填充。更新ctrl1时触发:

PARAMETERS [Ctrl1 input] Long;
SELECT table1.column1, table1.column2
FROM (table1 INNER JOIN table2 ON table1.column2 = table2.column1) INNER JOIN table3 ON table2.column2 = table3.column3
WHERE (((table3.column1)=[Ctrl1 input]))
ORDER BY table1.column2;

这是基于与table3.column1 中的值匹配的表单参数,该值在table3.column3 字段中也有一个值。现在,如果表单上的选择在table3.column3 中没有匹配值,则列表框保持为空。在这种情况下,我想返回 SELECT table1.column1, table1.column2 的完整列表,而不需要所有的连接和约束。 (列表很长,所以我只想在绝对必要时使用整个东西。)

在 SQL 中,case 函数似乎可以完成我想要的,类似于以下内容:

PARAMETERS [Ctrl1 input] Long;
CASE WHEN  (SELECT table3.column3 WHERE (table3.column2 = [Ctrl1 Input]) IS NOT NULL)
    THEN 
        SELECT table1.column1, table1.column2
        FROM (table1 INNER JOIN table2 ON table1.column2 = table2.column1) INNER JOIN table3 ON table2.column2 = table3.column3
    ELSE 
        SELECT table1.column1, table1.column2

但我无法在 Access 查询中使用 case

IIf 声明似乎也可以,

PARAMETERS [Ctrl1 input] Long;
IIf(
    (SELECT  table3.column3 WHERE (table3.column1 = [Ctrl1 input]) IS NOT NULL),
    (SELECT table1.column1, table1.column2 FROM (table1 INNER JOIN table2 ON table1.column2 = table2.column1) INNER JOIN table3 ON table2.column2 = table3.column3),
    (SELECT table1.column1, table1.column2)
    )

但 Access 不会接受,说它需要 SELECTINSERTDELETE 等。另外,在测试 SELECT IIf 时,我得到的东西说它只能返回一个值,所以这对我不起作用。

所以,我已经看到在 VBA 中同时使用 caseIIf 并在查询中使用 THAT 的文章,但我无法找到足够清晰的示例来了解如何转换我的把自己的情况变成一个模块然后调用它。我不使用 VBA,几乎不使用 SQL。在深入研究 VBA 之前,我想知道:

  1. 我能用 VBA 完成我想要的吗?
  2. caseIIf 或其他方法是否存在论据?
  3. 在函数中,我应该传递什么值?表单上 ctrl1 的数据?
  4. 我要求函数返回什么,如何返回?这是通过在函数本身中设置myfunction = the code that produces the dataset I need 来实现的吗?

我想我了解如何在查询中使用该函数,只要我了解该函数的输出类型即可。

提前感谢您提供任何见解和信息。

注意:我使用的是 Access 2016,但文件本身是 2002-2003 格式,因为这显然与我们的 GIS 软件兼容。

【问题讨论】:

  • IIF() 是正确的,您只是在错误的位置/顺序进行操作。 if 语句将在您选择的 WHERE 条件中使用,而不是之前。但就此而言,您也可以在调用 sql 之前在 VBA 中对其进行测试。老实说,您发布的代码太混乱/格式不正确,我不想尝试更多地对其进行解码,但我可以看到这至少是您的问题之一
  • @Matt 如果FROM 发生在它之前,我如何解决FROM 的变化取决于IIf 的结果?为混乱道歉。正如我所说,我不懂语言。如果我使用通用字段和表名会更好吗?当我查找每个函数的语法时,示例非常简单,我不知道如何调整格式,不知道一般的 SQL 方法。
  • 老实说,您可能应该测试该值并使用 VBA if then 逻辑来设置查询字符串,然后传递所需的字符串。您可以在 sql 中执行此操作,但您希望左加入您的可选表,然后在 JOIN 和 WHERE 中使用 IF() 语句来说明何时满足或不满足条件。

标签: sql vba ms-access-2003


【解决方案1】:

如果不需要IIF 或VBA 的控件为空(或未找到匹配项),有一种方法可以让Access 不过滤某些内容。您需要告诉 Access,如果输入为空,则只返回所有内容。您在顶部的查询将如下所示。

SELECT table1.column1, table1.column2
    FROM 
        (SELECT table1.column1, table1.column2
        FROM table1 
        INNER JOIN table2 
        ON table1.column2 = table2.column1)
INNER JOIN table3 
ON table1.column2 = table3.column3
    WHERE table3.column1 = [Ctrl1 input]
    OR [Ctrl1 input] is null
ORDER BY table1.column2;

OR 行告诉 Access “你知道吗,如果我没有告诉你该怎么做,就给我整张桌子”。列表框的填充方式无关紧要,此代码只关心列表框中的内容,而不关心它是如何到达那里的。像这样的代码可以放在 Access 查询的 SQL 视图中。

【讨论】:

  • 感谢您的回复。当我使用它时,会提示我输入 sq.column1 和 sq.column2 的值,并且无论我在控制框中选择什么,最终列表中都不会显示任何值。在引用它之前,我是否需要将某些东西存储为“sq”?我也有语法问题 w 另外,这个解决方案并没有解决全部问题 - 当在框中的选择和表 3 之间找不到匹配时,我试图获得完整的选项集,而不仅仅是当控制框为空时。
  • 关于 'sq' 问题,这是 Access 没有正确处理 SQL 别名的问题,这让我感到惊讶,但通过将代码更改为不使用别名来纠正。我想我可以通过添加OR table3.column1 != [Crt1 input] 让它返回不匹配。我将编辑我的答案以涵盖这些更改。
  • 从头开始,OR table3.column1 != [Ctrl1 input] 将返回所有内容,无论输入中有什么内容(如果 Access 将运行该语法)。如果您确实需要它在没有匹配项时显示所有内容,那么您可能确实需要IIF 和 VBA(如果可能的话)。我不知道该怎么做。我建议改变设计;如果没有匹配表明进程需要有效值或 null,则让它抛出错误。
  • 谢谢。目前我只是将异常硬编码到OR 中,因为它们相对较少。不理想,但即使没有匹配项,我也需要获得整个列表。谢谢。 (我要补充一点,上面的第一个SELECT 似乎是多余的。这与我添加OR [crtl1 input] is null 的初始查询相同。)
  • 是的,加了OR语句也是一样的,就是这个思路;执行与您的语句相同的操作,或者返回所有内容。
猜你喜欢
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-26
  • 2020-10-26
  • 2020-01-19
  • 1970-01-01
  • 2020-08-25
相关资源
最近更新 更多