ODBC SQL中HAVING子句使用ROUND函数报错的原因咨询
ODBC执行含ROUND的HAVING子句报错原因及解决方案
你的SQL语句如下:
SELECT SALES_LEDGER.ACCOUNT_REF, SALES_LEDGER.BALANCE FROM SALES_LEDGER INNER JOIN AUDIT_SPLIT ON SALES_LEDGER.ACCOUNT_REF = AUDIT_SPLIT.ACCOUNT_REF GROUP BY SALES_LEDGER.ACCOUNT_REF, SALES_LEDGER.BALANCE HAVING ROUND(SUM(AUDIT_SPLIT.GROSS_AMOUNT), 2) <> SALES_LEDGER.BALANCE;
报错原因
你遇到的ODBC: ERROR [42000] Syntax error: Invalid filter in HAVING clause错误,核心原因是你使用的ODBC驱动对应的数据库(大概率是Access/Jet这类桌面型数据库,因为Excel可直接执行简化版语句)的SQL语法兼容性有限,不支持在HAVING子句中直接对聚合函数的结果嵌套ROUND这类函数调用,这类数据库对HAVING子句的表达式有更严格的语法限制。
而Excel内置的查询引擎对语法宽松度更高,会自动适配无函数嵌套的聚合表达式,所以去掉ROUND后能正常运行,但无法处理精度差异问题。
解决方案
可以通过两种方式规避这个语法限制,同时保留ROUND的精度处理逻辑:
方案一:将ROUND计算放到SELECT子句,用别名关联HAVING
把聚合+ROUND的计算结果定义为别名,在HAVING子句中直接引用该别名:
SELECT SALES_LEDGER.ACCOUNT_REF, SALES_LEDGER.BALANCE, ROUND(SUM(AUDIT_SPLIT.GROSS_AMOUNT), 2) AS CALCULATED_BALANCE FROM SALES_LEDGER INNER JOIN AUDIT_SPLIT ON SALES_LEDGER.ACCOUNT_REF = AUDIT_SPLIT.ACCOUNT_REF GROUP BY SALES_LEDGER.ACCOUNT_REF, SALES_LEDGER.BALANCE HAVING CALCULATED_BALANCE <> SALES_LEDGER.BALANCE;
方案二:用子查询预计算聚合结果
先通过子查询完成分组聚合和ROUND处理,再与原表关联筛选:
SELECT sl.ACCOUNT_REF, sl.BALANCE FROM SALES_LEDGER sl INNER JOIN ( SELECT ACCOUNT_REF, ROUND(SUM(GROSS_AMOUNT), 2) AS CALCULATED_BALANCE FROM AUDIT_SPLIT GROUP BY ACCOUNT_REF ) AS split_sum ON sl.ACCOUNT_REF = split_sum.ACCOUNT_REF WHERE split_sum.CALCULATED_BALANCE <> sl.BALANCE;
内容的提问来源于stack exchange,提问作者elector
相关产品推荐
相关产品推荐

