问题描述
CREATE TABLE T1 (
`a` INTEGER,`b` DATETIME,`c` VARCHAR(5)
);
INSERT INTO T1
(`a`,`b`,`c`)
VALUES
('5678','2008-01-01 12:00','12.34'),('5678','2008-01-01 12:01',NULL),'2008-01-01 12:02','2008-01-01 12:03','23.45'),'2008-01-01 12:04',NULL);
我需要执行的是
SELECT * FROM(
SELECT a,b,c from T1
)AS Q GROUP BY c ORDER BY a,b;
哪个给:
5678 2008-01-01 12:00:00 12.34
5678 2008-01-01 12:01:00 NULL
5678 2008-01-01 12:03:00 23.45
H2暗示(并接受)的是
SELECT * FROM(
SELECT a,c from T1
)AS Q GROUP BY a,c ORDER BY a,c;
哪个给
5678 2008-01-01 12:00:00 12.34
5678 2008-01-01 12:01:00 NULL
5678 2008-01-01 12:02:00 NULL
5678 2008-01-01 12:03:00 23.45
5678 2008-01-01 12:04:00 NULL
根据您的一些建议,这些是查询和结果。
建议1:
SELECT max(a) as a,max(b) as b,c
FROM (
SELECT a,c from T1
) AS Q
GROUP BY c
ORDER BY a,b;
给予
5678 2008-01-01 12:00:00 12.34
5678 2008-01-01 12:03:00 23.45
5678 2008-01-01 12:04:00 NULL
建议2:
SELECT *
FROM (
SELECT a,c from T1
) AS Q
GROUP BY c,a,b
ORDER BY a,b;
给予
5678 2008-01-01 12:00:00 12.34
5678 2008-01-01 12:01:00 NULL
5678 2008-01-01 12:02:00 NULL
5678 2008-01-01 12:03:00 23.45
5678 2008-01-01 12:04:00 NULL
===============================
如何在获得所需结果的同时适当更改语法以适应H2需求?
解决方法
现在,针对修改后的问题。根据示例数据,在H2中可以执行以下操作:
select t1.*
from t1
join (
select c,min(b) as min_b from t1 group by c
) x on t1.c is not distinct from x.c and t1.b = x.min_b
order by t1.b;
结果:
A B C
---- --------------------- ------
5678 2008-01-01 12:00:00.0 12.34
5678 2008-01-01 12:01:00.0 <null>
5678 2008-01-01 12:03:00.0 23.45
用于重现案例的示例数据脚本为:
create table t1 (
a integer,b datetime,c varchar(5)
);
insert into t1 (a,b,c) values
('5678',timestamp '2008-01-01 12:00:00','12.34'),('5678',timestamp '2008-01-01 12:01:00',null),timestamp '2008-01-01 12:02:00',timestamp '2008-01-01 12:03:00','23.45'),timestamp '2008-01-01 12:04:00',null);
,
H2行为正常。较旧版本的MySQL允许执行查询,即使根据ANSI / ISO SQL和几乎所有其他SQL实现(SQLite除外),查询仍然无效。
中写了一个解释它的示例您必须更正查询才能使用H2。
规则是选择列表的每一列都必须在聚合函数内,或者必须在GROUP BY子句中命名。
您可以这样解决:
SELECT MAX(a) AS a,MAX(b) AS b,c FROM(
SELECT a,c from T1
)AS Q GROUP BY c ORDER BY a,b;
这符合规则,因为a
和b
在聚合函数中,而c
在GROUP BY
中。
MySQL 5.7和更高版本默认行为正确,并通过语义对组进行强制。
,您可能正在使用用于接受此类查询的MySQL 5.7.5或更早版本。如果您使用的是更新的MySQL,则可能启用了旧的/格式错误的语法。
查询:
SELECT *
FROM (
SELECT a,c from T1
) AS Q
GROUP BY c
ORDER BY a,b;
格式错误。为什么?因为必须将GROUP BY
子句中未包括的列(在这种情况下为a
和b
)汇总到选择列表中。您的选择列表包括所有列,自使用*
以来没有任何列。
此格式错误的MySQL查询不符合SQL标准,并且会为非聚合列产生随机值。 这是您应用程序中的实际错误。
但是,H2会正确拒绝它,并要求您对其进行修复。您可以执行任何有效的替代选择,例如:
SELECT c,max(a) as a,max(b) as b
FROM (
SELECT a,b;
或者也许:
SELECT *
FROM (
SELECT a,c from T1
) AS Q
GROUP BY c,a,b
ORDER BY a,b;
,
如果仅需要查询H2,则可以使用非标准PostgreSQL样式的DISTINCT ON
子句来代替分组查询:
SELECT DISTINCT ON(C) A,B,C FROM T1 ORDER BY A,B;
A
和B
的值将基于ORDER BY
子句进行选择。