我们在使用子查询查询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所述)解决了这个问题。
我不明白为什么要使用相同的字段和相同的表使用别名。为什么不简单地使用这样的查询:
SELECT count(id) FROM Foo
这个问题与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