我在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 claused中使用括号:http://nm1m.blogspot.com/2007/10/multiple-left-joins-in-ms-access.html
它给出了错误Invalid use of Null
,这对我来说没有意义,因为我没有执行空检查等。这里有什么问题?我正在尝试拉出TableB中的一个字段来显示(但是还没有把它放在选择部分)。
答案 0 :(得分:5)
Access喜欢它的括号。在连接周围添加更多括号。
CLng
函数需要非空值。您可以使用CLng(Nz(TableA.FieldA, "0")) >= 119593451
解决此问题。但是,如果该字段是数字的,那么为什么你会在文本中开始使用它?这是一个严重的问题,我强烈建议立即修改(如果可能的话)将数据类型更改为数字类型。
但是你有另一个问题。如果你在LEFT JOIN
子句中提出一个条件,那么WHERE
对于一个表是没有意义的,正如你在查询中所做的那样!可以更改为INNER JOIN
或将TableA
上的条件放入ON
的{{1}}子句中。如果Access不允许此语法,则更改为派生表:
LEFT JOIN
注意:添加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;
可能有效但可能无效。在Access中,它可以100%安全,但SQL Server中的此类查询不安全,因为无法保证应用条件的顺序。显然,在SQL Server中,即使在NULL且没有WHERE TableA.FieldA IS NOT NULL
函数时也可以转换为整数,但这一点仍然有效:不要养成依赖CLng
的某种想象顺序的习惯保护您免受无效类型转换的条件:相反,您必须处理可能出错的表达式中的无效类型转换 - 这是最佳做法。