带有子查询的COUNT在H2数据库上失败并显示“重复列名”

时间:2017-11-14 10:02:56

标签: sql h2

我们在使用子查询查询COUNT时意识到H2的奇怪行为。

准备表:

CREATE TABLE Foo
(
  id INT PRIMARY KEY AUTO_INCREMENT,
  fieldName VARCHAR(30) NOT NULL,
);

测试简单查询(工作正常):

SELECT F1.id, F2.id from Foo as F1 INNER JOIN Foo F2 on F1.id = F2.id

使用count:

测试相同的查询
SELECT count(*) FROM (
  SELECT F1.id, F2.id from Foo as F1 INNER JOIN Foo F2 on F1.id = F2.id
) q;

出现以下错误:

  

[42S21] [42121]重复列名“ID”; SQL语句:       select count(*)FROM(

有任何解决方法吗?

更新: 问题在于,在准备子查询列名时擦除了原始表名,实际上我有:

SELECT count(*) FROM (
  SELECT id, id from q
); 

添加别名(如Abdul Rasheed所述)可解决问题。

2 个答案:

答案 0 :(得分:1)

我不明白为什么要使用相同的字段和相同的表来使用别名。 为什么不使用这样的查询:

responses

答案 1 :(得分:0)

此问题与H2无关,但在所有SQL数据库中都会发生。允许使用顶级SQL SELECT语句以相同的名称投影两列,但不允许使用子查询(尤其是派生表)。这与是否曾经引用过子查询中不明确的列名无关。

解决方案是显式别名您的列:

SELECT count(*) FROM (
  SELECT f1.id AS f1_id, f2.id AS f2_id 
  FROM foo AS f1 
  INNER JOIN foo f2 ON f1.id = f2.id
) q;

或者完全避免在派生表中进行投影,因为您无需使用它来计算计数值:

SELECT count(*) FROM (
  SELECT 1
  FROM foo AS f1 
  INNER JOIN foo f2 ON f1.id = f2.id
) q;

此时,您显然可以完全避免派生表:

SELECT count(*) 
FROM foo AS f1 
INNER JOIN foo f2 ON f1.id = f2.id;

使用H2 1.4.198或更高版本时的另一种方法是使用窗口函数来计算每一行的计数值:

SELECT f1.id AS f1_id, f2.id AS f2_id, count(*) OVER ()
FROM foo AS f1 
INNER JOIN foo f2 ON f1.id = f2.id