【问题标题】:H2: Duplicate column names in count query with nested queryH2:使用嵌套查询的计数查询中的列名重复
【发布时间】:2019-03-13 04:51:42
【问题描述】:

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

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

  • 客户:ID、姓名、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 查询?
  • @LukasEder 我们使用 Jooq DSL 构建查询,然后我们使用 dsl.fetchCount(query) 计算 query 返回的行数。

标签: java sql database h2 jooq


【解决方案1】:

问题

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

【讨论】:

  • 谢谢@Lukas。我们实现了选项 1,创建一个列名明确的视图,然后查询该视图。
猜你喜欢
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-22
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多