H2 数据库:在 CTE 中使用窗口函数时出错

Posted

技术标签:

【中文标题】H2 数据库:在 CTE 中使用窗口函数时出错【英文标题】:H2 database : Error when using window function inside CTE 【发布时间】:2020-08-13 12:00:52 【问题描述】:

使用 H2 数据库(版本 1.4.200)我在 CTE 中使用窗口函数时遇到了非常奇怪的错误。当我在CTEOVER() 子句中包含窗口函数字段时,它可以正常工作,但是当我尝试在OVER() 子句中添加ORDER BY/PARTITION BY 时,我遇到了以下错误:'[42000][42000] Syntax error in SQL statement "WITH statement supports only SELECT, TABLE, VALUES, CREATE TABLE, INSERT, UPDATE, MERGE or DELETE statements" ' 非工作代码示例:

WITH cte AS( 
  SELECT ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn 
  FROM TEST.HOLDING
)    
SELECT * 
FROM cte

一个澄清:当我使用带有 PARTITION BY\ORDER BY 部分不在CTE 内的 Windows 函数运行语句时,它运行良好。 工作代码示例:

SELECT ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn 
FROM TEST.HOLDING

问题的测试用例:

CREATE TABLE PUBLIC.HOLDING(
CUST_NAME VARCHAR(50),
ORDER_DATE DATE
);

INSERT INTO PUBLIC.HOLDING(CUST_NAME, ORDER_DATE)
VALUES('Customer1',TO_DATE('20200201','YYYYMMDD')),
      ('Customer1',TO_DATE('20200202','YYYYMMDD')),
      ('Customer2',TO_DATE('20200201','YYYYMMDD')),
      ('Customer2',TO_DATE('20200202','YYYYMMDD'));

WITH cte AS(
SELECT CUST_NAME,
       ORDER_DATE,
       ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn
FROM PUBLIC.HOLDING
)

SELECT *
FROM cte;

SELECT CUST_NAME,
       ORDER_DATE,
       ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn
FROM PUBLIC.HOLDING;

【问题讨论】:

请提供您的查询的简化版本(证明错误的版本)。一个工作版本也会有所帮助。 两个样本都错误地使用ORDER 作为没有双引号的标识符,如果在最新的 H2 中正确指定 (TEST."ORDER"),两者都可以工作。请提供一些真正引发此类错误的代码。 感谢您的澄清,我提供了真实的表名 如果此类表是使用随机数据创建的,则更新后的问题中的两个查询都可以在 1.4.200 中正常工作。您需要提供一些确实不起作用的测试用例(最好包含CREATE TABLE 语句和一些INSERT INTO 语句以用示例数据填充此表)。 我实际使用的是1.4.200版 【参考方案1】:

你应该告诉我们你使用的是哪个数据库。如果你使用sql server,请检查你的代码,我猜'with'前面是否有';'。

;WITH cte AS( 
  SELECT ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn 
  FROM TEST.HOLDING
)    
SELECT * 
FROM cte;

【讨论】:

我正在使用 H2 数据库

以上是关于H2 数据库:在 CTE 中使用窗口函数时出错的主要内容,如果未能解决你的问题,请参考以下文章

使用(递归?)CTE + 窗口函数将销售订单归零?

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

具有 CTE 的 T-SQL 窗口函数,使用先前计算的值

重写查询以使用除 CTE 和子查询之外的窗口函数

WinFrom 创建窗口句柄时出错

在另外一个类中调用一个窗口类中的listbox的控制变量的成员函数出错!