如何在 HSQLDB 中找到顺序编号的空白?

Posted

技术标签:

【中文标题】如何在 HSQLDB 中找到顺序编号的空白?【英文标题】:How to find gaps in sequential numbering in HSQLDB? 【发布时间】:2018-01-25 02:12:21 【问题描述】:

我正在尝试使 this answer made for mysql 适应 HSQLDB(2.4.0,通过 Hibernate 5.2.12)。我已将 MySQL 的“IF”函数替换为“CASE WHEN”调用,如下所示:

SELECT
 CONCAT(z.expected, CASE WHEN z.got-1>z.expected THEN CONCAT(' thru ',z.got-1) ELSE '' END) AS missing
FROM (
 SELECT
  @rownum\\:=@rownum+1 AS expected,
  CASE WHEN @rownum=id THEN 0 ELSE @rownum\\:=id END AS got
 FROM
  (SELECT @rownum\\:=0) AS a
  JOIN Notices
  WHERE fonds_cote = '1Fi'
  ORDER BY id
 ) AS z
WHERE z.got!=0;

: 被转义以避免来自 Hibernate 的解析错误。仍然,它不起作用,我面临:

org.hsqldb.HsqlException: unexpected token: (
    at org.hsqldb.error.Error.parseError(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserBase.unexpectedToken(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserDQL.XreadSelect(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserDQL.XreadQuerySpecification(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserDQL.XreadSimpleTable(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserDQL.XreadQueryPrimary(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserDQL.XreadQueryTerm(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserDQL.XreadQueryExpressionBody(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserDQL.XreadQueryExpression(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserDQL.compileCursorSpecification(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserCommand.compilePart(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.ParserCommand.compileStatement(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.Session.compileStatement(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.StatementManager.compile(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.Session.execute(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source) ~[hsqldb-2.4.0.jar:2.4.0]
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]

什么是正确的语法?还是在 HSQLDB 中有更好的方法?

【问题讨论】:

【参考方案1】:

问题在于变量@rownum的使用。 HSQLDB 不支持此功能。

使用 HSQLDB,您可以通过简单的方式完成。

假设表名为CUSTOMER,序列列名为ID。下面的查询展示了 SEQUENCE_ARRAY 如何工作并用于查找缺失值。

-- this returns consecutive numbers within a fixed range
SELECT * FROM UNNEST (SEQUENCE_ARRAY(1, 1000, 1))
-- this returns all the possible consecutive numbers for an existing table
SELECT * FROM UNNEST (SEQUENCE_ARRAY((SELECT MIN(ID) FROM CUSTOMER), (SELECT MAX(ID) FROM CUSTOMER), 1))

-- this returns the list of unused IDs.
SELECT * FROM UNNEST (SEQUENCE_ARRAY((SELECT MIN(ID) FROM CUSTOMER), (SELECT MAX(ID) FROM CUSTOMER), 1)) SEQ(IDCOL)
LEFT OUTER JOIN CUSTOMER ON CUSTOMER.ID = SEQ.IDCOL WHERE CUSTOMER.ID IS NULL

【讨论】:

谢谢。我现在有一个 Hibernate 错误:“NonUniqueDiscoveredSqlAliasException:在自动发现本机 sql 查询期间遇到重复的 sql 别名 [ID]” 我稍作更改,为序列列使用不同的名称。 它现在正在返回结果,但我不得不重新处理查询,因为除了 id 之外,我还有另一个条件要满足。我想出了“SELECT DISTINCT(id) FROM UNNEST (SEQUENCE_ARRAY((SELECT MIN(id) FROM Notices WHERE Notices.fonds_cote = '1Fi'), (SELECT MAX(id) FROM Notices WHERE Notices.fonds_cote = '1Fi') , 1)) SEQ(id) LEFT OUTER JOIN Notices ON Notices.id = SEQ.id WHERE NOT EXISTS(SELECT n.id FROM Notices n WHERE n.id = Notices.id AND n.fonds_cote = '1Fi')" 但是这很慢,你有更快的方法吗?

以上是关于如何在 HSQLDB 中找到顺序编号的空白?的主要内容,如果未能解决你的问题,请参考以下文章

hsqldb 中,如何指定数据库文件存放位置?

如何找出给定 JBoss 实例的 HSQLDB 版本

Nvivo 10 如何调整Node顺序?使其按自己想要的顺序排列

如何以二进制形式编写 hsqldb?

如何在此类图像中找到最大的空白空间?

用endnote插入文献,第100条后序号后面的空白变大,1-99条没有问题,见图。请问该如何解决?