H2:使用嵌套查询的计数查询中的列名重复

Posted

技术标签:

【中文标题】H2:使用嵌套查询的计数查询中的列名重复【英文标题】:H2: Duplicate column names in count query with nested query 【发布时间】: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 返回的行数。 【参考方案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,创建一个列名明确的视图,然后查询该视图。

以上是关于H2:使用嵌套查询的计数查询中的列名重复的主要内容,如果未能解决你的问题,请参考以下文章

嵌套 AngularJS 指令中的查询选择器

Django-使用 ManyToManyField 查询嵌套模型中的重复查询

如何优化执行嵌套在 group-by 子句中的计数的 SQL 查询?

嵌套多映射 Dapper 分页查询中的重复字段名称问题

使用 DELETE 逻辑不在嵌套查询中的最快性能 [重复]

使用两个条件获取计数的嵌套查询