日期字段上的左连接 + Where 子句

Posted

技术标签:

【中文标题】日期字段上的左连接 + Where 子句【英文标题】:Left Join + Where clause on Date Field 【发布时间】:2014-07-02 18:42:20 【问题描述】:

在左连接的右侧,我无法在日期字段上设置 Where 子句。如果更改为 Inner Join,或者我在非日期字段上设置 Where ,它会完美运行。

这会失败并出现“条件表达式中的数据类型不匹配”错误:

SELECT tblFuture.ContractNo
FROM tblFuture LEFT JOIN qryActualDeliveriesDump_summarized
ON tblFuture.ContractNo = qryActualDeliveriesDump_summarized.ContractNo
WHERE qryActualDeliveriesDump_summarized.Dt=#2/1/2014#;

这很好用:

SELECT tblFuture.ContractNo
FROM tblFuture INNER JOIN qryActualDeliveriesDump_summarized
ON tblFuture.ContractNo = qryActualDeliveriesDump_summarized.ContractNo
WHERE qryActualDeliveriesDump_summarized.Dt=#2/1/2014#;

同样如此:

SELECT tblFuture.ContractNo
FROM tblFuture LEFT JOIN qryActualDeliveriesDump_summarized
ON tblFuture.ContractNo = qryActualDeliveriesDump_summarized.ContractNo
WHERE qryActualDeliveriesDump_summarized.ContractNo=41012;

字段 ContractNo 是 Long 类型,字段 Dt 来自调用 DateSerial(someyear, somemonth, someday) 的查询。这闻起来像一个访问错误,但谷歌搜索对我来说一无所获。我正在使用 Access 2010 32 位。

【问题讨论】:

将条件移至联接。 qryActualDeliveriesDump_summarized.Dt 是日期字段吗? 孙 W 金:是的。它是从返回 Date 数据类型 (DateSerial) 的函数生成的。 【参考方案1】:

当使用外连接时,您要么必须在 where 子句中使用 OR null,或者更恰当地说,在通过过滤连接本身生成连接的笛卡尔形式之前进行过滤。这仅适用于未返回所有结果的表上的过滤器(在这种情况下为 qryActualDeliveriesDump_summarized)。 Cartesian 导致来自 qryActualDeliveriesDump_Summarized 的空记录 where 子句过滤掉那些空记录,但您需要它们。那么该怎么办呢?

解决方案:将过滤器添加到连接中,使其在笛卡尔生成之前发生,或将or field is null 添加到 where 子句。

SELECT tblFuture.ContractNo
FROM tblFuture LEFT JOIN qryActualDeliveriesDump_summarized
ON tblFuture.ContractNo = qryActualDeliveriesDump_summarized.ContractNo
and qryActualDeliveriesDump_summarized.Dt=#2/1/2014#;

或者(虽然这不是那么干净)

SELECT tblFuture.ContractNo
FROM tblFuture LEFT JOIN qryActualDeliveriesDump_summarized
ON tblFuture.ContractNo = qryActualDeliveriesDump_summarized.ContractNo
WHERE (qryActualDeliveriesDump_summarized.Dt=#2/1/2014# OR qryActualDeliveriesDump_summarized.Dt is null);

后者有它自己的问题,例如如果字段可以为空,您无法分离出由于基表中的连接与空值而为空的记录。这通常不是问题,但在某些情况下可能会出现问题,这就是为什么向联接添加条件是一个更好的答案。

但是在访问... 它必须分为两个步骤:第一步获取一组包含过滤结果的数据,然后进行连接。否则,外连接中的空值也将被消除。

SELECT tblFuture.ContractNo
    FROM tblFuture 
    LEFT JOIN (Select * from qryActualDeliveriesDump_summarized where   qryActualDeliveriesDump_summarized.Dt=#2/1/2014#) B on 
    ON tblFuture.ContractNo = B.ContractNo

【讨论】:

第一个返回“不支持连接表达式”,第二个返回相同的“数据不匹配错误”。 xQbert:很棒的发现! SELECT tblFuture.ContractNo FROM tblFuture LEFT JOIN (SELECT * FROM qryActualDeliveriesDump_summarized WHERE YEAR(Dt)=2014) AS innie ON tblFuture.ContractNo = innie.ContractNo; 我敢肯定,在真正的数据库中,您的其他建议会非常有效,但 Access 不喜欢它们。由于知识库链接,仍然接受答案。

以上是关于日期字段上的左连接 + Where 子句的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 linq lambda 扩展方法执行带有 where 子句的左外连接

MySQL 上的左连接 + 计数 + 总和

如何在 EF / EF Core 中的第二个表上实现具有某些条件的左连接?

带有两个不同 where 子句的内/左连接

将左连接重写为索引视图的 where 子句

数据库中的左连接(left join)和右连接(right join)区别