我想知道是否可以在嵌套查询中保留表名以避免 Duplicate column name
错误。
作为一个最小的例子,我有下表:
- CUSTOMERS:ID、NAME、CITY_ID
- 城市:ID、姓名、邮政编码
以下查询因错误 Duplicate column name "NAME"
而失败:
SELECT COUNT(*) FROM (
SELECT CUSTOMERS.NAME, CITY.NAME
FROM CUSTOMERS JOIN CITIES ON CUSTOMERS.CITY_ID = CITIES.ID
)
显然 H2 去除了嵌套查询中的表名,因此产生了名为 NAME
的两列
(参见 COUNT with subquery fail on H2 database with "Duplicate column name")。
一个解决方案是在嵌套查询中使用列别名,但由于其他项目要求我想避免使用它(即,我想使用 Jooq 生成的列标识符来构建查询)。
你知道强制 H2 在嵌套查询中保留表名的方法吗?
最佳答案
问题
这是一个已知的 jOOQ 问题,特定于 DSLContext.fetchCount(Select)
的用法: https://github.com/jOOQ/jOOQ/issues/7867
它与 H2 无关,但发生在所有数据库中,因为所有数据库都允许在顶级选择中使用重复的列名,但在派生表中不允许。
jOOQ 应该按如下方式消除列名的歧义:
SELECT COUNT(*) FROM (
SELECT CUSTOMERS.NAME AS C1, CITY.NAME AS C2
FROM CUSTOMERS JOIN CITIES ON CUSTOMERS.CITY_ID = CITIES.ID
)
但这很棘手,因为列可能会从 ORDER BY
子句中引用(由于 LIMIT
/FETCH
可能需要这样做子句),所以问题还没有解决。
解决方法
您必须自己解决这个问题。您有 3 个选择:
- 在运行计数时重写查询,或者一般使用列别名重写
- 手动运行普通计数查询
- 在 H2 1.4.198(截至今天尚未发布)中,将实现窗口函数,因此您可以投影
COUNT(*) OVER ()
表达式来计算每个窗口的计数值行。
关于java - H2:使用嵌套查询的计数查询中的重复列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52703587/