0

我在 Access 中有这个 SQL 查询,它工作正常:

SELECT TableA.FieldA As [Code],
   Count(TableA.FieldC) AS [Count]
FROM ((MainTable)
   LEFT JOIN TableA ON MainTable.FieldB = TableA.FieldB)
WHERE (((MainTable.DateOf)>=#1/1/2012#))
   AND Clng(TableA.FieldA) >= 119593451
   AND Clng(TableA.FieldA) <= 119593461
GROUP BY TableA.FieldA;

但是当我尝试另一个左连接时,就像这样:

SELECT TableA.FieldA As [Code],
   Count(TableA.FieldC) AS [Count]
FROM ((MainTable)
   LEFT JOIN TableA ON MainTable.FieldB = TableA.FieldB)
   LEFT JOIN TableB ON TableA.FieldD = TableB.FieldD
WHERE (((MainTable.DateOf)>=#1/1/2012#))
   AND Clng(TableA.FieldA) >= 119593451
   AND Clng(TableA.FieldA) <= 119593461
GROUP BY TableA.FieldA;

我在基于此的 FROM 子句中使用括号:http: //nm1m.blogspot.com/2007/10/multiple-left-joins-in-ms-access.html

它给出了错误Invalid use of Null,这对我来说没有意义,因为我没有执行空检查等。这里有什么问题?我试图在 TableB 中拉出一个字段来显示(但还没有把它放在选择部分)。

4

1 回答 1

5

Access 喜欢它的括号。在连接周围添加更多括号。

CLng函数需要一个非空值。您可以使用CLng(Nz(TableA.FieldA, "0")) >= 119593451. 但是,如果该字段是数字的,那么您到底为什么要以文本开头呢?这是一个严重的问题,我强烈建议通过将数据类型更改为数字类型来立即修复(如果可能的话)。

但是你还有另一个问题。LEFT JOIN如果您在WHERE子句中放置一个条件,就像您在查询中所做的那样,那么对表来说毫无意义!要么更改为 a ,INNER JOIN要么将您的条件放在.TableAON子句中LEFT JOIN。如果 Access 不允许此语法,则更改为派生表:

SELECT
   TableA.FieldA As [Code],
   Count(TableA.FieldC) AS [Count]
FROM
   (
      (
         (MainTable)
         LEFT JOIN (
            SELECT * FROM TableA
            WHERE
               Clng(Nz(TableA.FieldA, "0")) >= 119593451
               AND Clng(Nz(TableA.FieldA, "0")) <= 119593461
         ) TableA ON MainTable.FieldB = TableA.FieldB
      )
      LEFT JOIN TableB ON TableA.FieldD = TableB.FieldD
   )
WHERE (((MainTable.DateOf)>=#1/1/2012#))
GROUP BY TableA.FieldA;

注意:添加WHERE TableA.FieldA IS NOT NULL可能有效,但可能无效。在 Access 中它可能是 100% 安全的,但在 SQL Server 中这样的查询将不安全,因为不能保证应用条件的顺序。显然,在 SQL Server 中,即使为 NULL 并且没有CLng函数,您也可以转换为整数,但这一点仍然有效:不要养成依赖某些想象的WHERE条件顺序来保护您免受无效类型转换的习惯:相反,您必须处理可能出错的表达式内的无效类型转换——这是最佳实践。

于 2012-12-21T19:43:08.217 回答