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

标签 java sql database h2 jooq

我想知道是否可以在嵌套查询中保留表名以避免 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/

相关文章:

mysql - SQL - 如果没有数据则插入到表中

.net - 使用 Visual Studio 2008 创建数据库

java - 单击按钮不会插入数据库?

java - 将 long 转换为 Int 在 '-1' 中返回?

sql - SQL 中的年度队列分析

mysql - 尽管有数据,但带有 MAX 函数的 HAVING 子句不返回任何数据

java - 使用 jenkins 插件检查 java 编码风格

java - 如何将图像上传到 SQLite 数据库?

php - 在数据库中插入行并更新其下面的行

.net - 如何在数据库中存储统计信息