【问题标题】:LEFT JOINing on additional criteria in MS Access左加入 MS Access 中的附加条件
【发布时间】:2010-01-06 20:13:31
【问题描述】:

我有以下 T-SQL 查询(一个简单的测试用例)在 MS SQL 中运行良好,但无法在 MS Access (JET-SQL) 中获得等效查询。问题是 LEFT JOIN 中的附加条件。 如何在 MS Access 中执行此操作?

T-SQL:

SELECT * FROM A 
LEFT OUTER JOIN B ON A.ID = B.A_ID 
                 AND B.F_ID = 3

JET-SQL(我目前拥有的,但 Access 崩溃了!):

SELECT * FROM dbo_A 
LEFT JOIN dbo_B ON (dbo_A.ID = dbo_B.A_ID AND dbo_B.F_ID = 3)

【问题讨论】:

  • 连接条件上不需要括号
  • T-SQL 示例是外连接是否重要?它本质上所做的就是返回 A 中的所有行。
  • @OMG Ponies - 如果没有括号,我会收到语法错误,访问崩溃... @Melvin - 不,OUTER 这个词是可选的。

标签: sql ms-access left-join


【解决方案1】:

您需要使用子选择来应用条件:

  SELECT *
  FROM dbo_A LEFT JOIN 
    [SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3]. AS dbo_B 
      ON dbo_A.ID = dbo_B.A_ID;

如果您在打开“SQL 92”兼容模式的情况下运行 Access,则可以执行更标准的操作:

  SELECT *
  FROM dbo_A LEFT JOIN 
    (SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3) AS dbo_B 
      ON dbo_A.ID = dbo_B.A_ID;

您需要在 Access 中进行编辑吗?如果没有,只需使用带有本机 T-SQL 的直通查询。如果是这样,我可能会为此创建一个服务器端视图,如果文字值是您要参数化的值(即 F_ID=3 实际上是 F_ID=N 其中 N是在运行时选择的值)。

顺便说一句,我每天在 Access 中编写这些子选择派生表 SQL 语句。这没什么大不了的。

【讨论】:

  • 是的,我知道我可以使用子选择,但它的速度要慢得多,所以我宁愿使用左连接。虽然我不知道直通查询选项,但效果很好! (此处为其他人提供更多信息:support.microsoft.com/kb/303968)。我将您的答案标记为已接受,因为它有效。谢谢!
  • 子选择是否较慢取决于两件事:1)所涉及的数据库引擎如何优化子选择与替代方案,在这种情况下很明显,2)选项是否是偶数可用的。在 Jet/ACE SQL 中,这不是因为您不能在相反方向定义多字段连接(即,一个来自 A=>B,另一个来自 B=>A)。与替代方案相比,SQL Server 可能对子选择进行了次优优化,但如果您使用的是 Jet/ACE,则必须遵循 Jet/ACE 的规则,因此提到了直通。
  • 我很确定左连接总是比子选择快。当然,在一个小数据集中或者如果您的数据库引擎可以优化(AKA 将您的子选择变成左连接),您不会看到差异,但是“左连接然后选择 n 行”将比“ n+1 选择”。绝对在我的情况下,SQL Server 运行左连接更快。
【解决方案2】:

当它崩溃或只是锁定时,您会收到错误消息吗?从 dbo_B 名称来看,我猜测这些是 Access 中的链接表。我相信当你进行这样的连接时,Access 不会告诉 SQL 服务器它需要连接的结果,它会说,“把两个表的所有行都给我”,然后它会尝试自己连接它们。如果表非常大,这可能会导致应用程序锁定。

您最好根据需要在 SQL Server 上创建一个视图。

【讨论】:

  • 绝对是个好主意,这是否意味着我的语法是正确的,只是 Access 无法处理它?
  • 我不知道 Access 本身是否有技术限制,但如果表是数百万行,那么运行 Access 的 PC 以及数据必须流过的网络是可能不知所措。
  • Jet/ACE 要求完整的表并自己进行连接是完全不正确的,除非有什么东西阻止 Jet/ACE 获取它需要的元数据以确定它是否可以通过整个事情关闭到服务器(99% 的时间应该是这种情况)。或者,可能是链接表(例如,可能是视图)的某些内容阻止了 Jet/ACE 完成这项工作。这是我能想到的唯一两种可能导致 Jet/ACE 使用提供的 SQL 请求完整表的情况。简而言之,这种情况发生的可能性非常非常小。
  • 创建视图是个好主意,但我没有创建视图的权限。
【解决方案3】:

我认为 ms 访问期望在 Joins ON 子句的每个部分中的两个表名。作为一个技巧,这对我有用:

SELECT * FROM A 
LEFT OUTER JOIN B ON A.ID = B.A_ID 
                 AND B.F_ID = IIF(True, 3, A.ID) 

A.ID 或表 A​​ 中的任何其他字段

【讨论】:

    【解决方案4】:

    从技术上讲,最后一个条件不是连接,而是与文字值的比较。将其放在 WHERE 子句中:

    SELECT *
    FROM a LEFT OUTER JOIN b ON a.ID = b.a_id
    WHERE b.f_id = 3;
    

    【讨论】:

    • 这不是真的。当 F_ID = 3 时,在左连接条件中检查 F_ID = 3 将为 B 中的所有值提供 null。将其放在 where 子句中根本不会返回它们。
    • 对不起,我的意思是当 F_ID 3 用于左连接时,你会得到 null。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    相关资源
    最近更新 更多