我遇到了一个问题,每当我尝试使用GROUP BY
时,H2都会告诉我需要在GROUP BY
子句中添加某些列名,因为根据我的研究,它是不清楚H2如何使用非重复数据对列进行排序。
这是一个详细说明的例子:
人员表
+------------+------------+
| ID | Name |
+============+============+
| 1 | John |
+------------+------------+
| 2 | Jane |
+------------+------------+
宠物表
+------------+------------+------------+------------+
| ID | PERSON_ID | NAME | BIRTHDATE |
+============+============+============+============+
| 1 | 1 | Rufus | 2012 |
+------------+------------+------------+------------+
| 2 | 1 | Ben | 2014 |
+------------+------------+------------+------------+
假设我想要属于约翰的所有最老的宠物。
SELECT PERSON.NAME, PET.NAME, PET.BIRTHDATE FROM PERSON
INNER JOIN PET ON PET.PERSON_ID = PERSON.ID
GROUP BY PERSON.NAME
ORDER BY PET.BIRTHDATE ASC
这在MySQL中完全有效,因为它只是按PERSON.NAME
分组,默认情况下,选择集合中的第一条记录。但是,在H2中,它需要具有MAX
,MIN
等聚合
正如您在本示例中所看到的,问题在于您可以使用MIN
来正确排序BIRTHDATE
,但似乎没有任何可用于排序的聚合函数{{1基于最早的NAME
?
答案 0 :(得分:0)
在这种情况下,你可以随时诉诸NOT EXISTS
,如果这个人没有生育日期较小的宠物,那么宠物就是最老的(如果两只宠物的年龄相同,两者都是最老的宠物)那个人,然后都被选中了):
SELECT p.NAME, q.NAME, q.BIRTHDATE
FROM PERSON p
INNER JOIN PET q ON q.PERSON_ID = p.ID AND NOT EXISTS (
SELECT * FROM PET WHERE PERSON_ID = p.ID AND BIRTHDATE < q.BIRTHDATE
)
ORDER BY q.BIRTHDATE ASC
如果你坚持GROUP BY
,你可以这样做:
SELECT a.name, b.name, b.BIRTHDATE FROM (
SELECT p.id, MIN(q.BIRTHDATE) birthdate FROM PERSON p
INNER JOIN PET q ON q.PERSON_ID = p.ID
GROUP BY p.ID
) o INNER JOIN PERSON a ON a.ID = o.ID
INNER JOIN PET b ON b.PERSON_ID = a.ID AND b.BIRTHDATE = o.BIRTHDATE
ORDER BY b.BIRTHDATE
如果您可以使用WITH
,则可以更轻松地编写查询。
答案 1 :(得分:0)
如果你想要最老的宠物,我建议:
SELECT p.NAME, pt.NAME, pt.BIRTHDATE
FROM PERSON p INNER JOIN
PET pt
ON pt.PERSON_ID = p.ID
WHERE pt.BIRTHDATE = (SELECT MIN(pt2.BIRTHDATE)
FROM pet pt2
WHERE pt2.PERSON_ID = PT.PERSON_ID
);
这明确选择了最早出生年份的宠物(每个人)。不需要聚合。
您也可以仅在JOIN
:
FROM
对此进行说明
SELECT p.NAME, pt.NAME, pt.BIRTHDATE
FROM PERSON p INNER JOIN
PET pt
ON pt.PERSON_ID = p.ID JOIN
(SELECT PERSON_ID, MIN(pt2.BIRTHDATE) as MINBT
FROM pet pt2
GROUP BY pt2.PERSON_ID
) pt2
ON pt2.PERSON_ID = PT.PERSON_ID;