如何为HSQL中的每个组选择列中具有最大值的行?

Posted

技术标签:

【中文标题】如何为HSQL中的每个组选择列中具有最大值的行?【英文标题】:How to select row with maximum value in column for each group in HSQL? 【发布时间】:2018-05-08 08:57:34 【问题描述】:

我在 HSQL 数据库中有一个名为 PERSON 的表,如下所示:

NAME(PK) | AGE | CITY   | ... many more here ... | 
--------------------------------------------------
aaa      |  12 |   nyc  | ...
bbb      |  12 |   nyc  | ...
ccc      |  10 |   nyc  | ...
ddd      |  34 |    la  | ...
eee      |  10 |    la  | ...

对于每个城市,我需要选择年龄最大的记录。如果对于一个给定的城市有多个记录的最大年龄相同,我仍然需要为这个城市选择一个记录(但可以任意选择)。

所以在上面的例子中我需要这个结果:

NAME(PK) | AGE | CITY | ... many more here ... | 
--------------------------------------------------
aaa      |  12 |  nyc | ...
ddd      |  34 |   la | ...

如果我得到 bbb 而不是 aaa 就可以了,但得到 aaa 和 bbb 就不行了。

仅在 city 列上使用 group by 并将 max(age) 作为聚合函数不起作用,因为这不允许我选择 age 和 city 以外的其他列,因为它们不在聚合中。我尝试进行分组,然后将结果加入表中,但这样我无法摆脱具有重复最大年龄的记录。这个查询:

SELECT NAME, CITY, AGE, [... many more here ...] 
FROM ( 
    SELECT max(age) AS maxAge, city 
    FROM PERSON
    GROUP BY CITY
) AS x
JOIN PERSON AS p 
ON p.city = x.city AND p.age = x.maxAge

产量:

NAME(PK) | AGE | CITY | ... many more here ... | 
--------------------------------------------------
aaa      |  12 |  nyc | ...
bbb      |  12 |  nyc | ...
ddd      |  34 |   la | ...

纽约市的两条记录应该只有一条。

【问题讨论】:

纽约市如何选择aaa或bbb? 可以任意,只要每个城市只选择一条记录即可 【参考方案1】:

如果您不关心订单,那么您可以使用 correlated subquery

select * 
from PERSON p
where name = (select name 
              from PERSON 
              where CITY = p.City 
              order by AGE desc, name asc -- neglate name if you want arbitrary ordering 
              LIMIT 1);

这将为每个城市选择一个名称。

【讨论】:

【参考方案2】:

相关子查询解决方案的现代 SQL 替代方案是 LATERAL 关键字:

SELECT * FROM 
 (SELECT DISTINCT CITY FROM PERSON) CITIES, 
 LATERAL 
 (SELECT * FROM PERSON WHERE CITY = CITIES.CITY ORDER BY AGE DESC LIMIT 1)

【讨论】:

这是否也有望比相关子查询执行得更好? 速度应该差不多。你需要一个关于 CITY 的索引来提高速度。

以上是关于如何为HSQL中的每个组选择列中具有最大值的行?的主要内容,如果未能解决你的问题,请参考以下文章

如何为每个键值选择具有最新时间戳的行?

Postgresql:如何为postgres中的相同时间戳选择“媒体”列中的最大值?

SQL:如何为一列中具有重复值的每组行选择一行?

从列中的最大 id 创建 HSQL 序列

如何为每个 ID 获取具有 max(TIMESTAMP) 的行? [复制]

如何编写 SQL 来选择具有每个组的最大值(值)的行?