H2:计数查询与嵌套查询中重复的列名称

时间:2018-10-08 13:38:27

标签: java sql database h2 jooq

我想知道是否可以在嵌套查询中保留表名,以避免Duplicate column name错误。

作为一个最小的示例,我有以下表格:

  • 客户: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在嵌套查询中保留表名的方法吗?

1 个答案:

答案 0 :(得分:0)

问题

这是一个已知的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 ()表达式以计算每一行的计数值。