Sql 选择group by中的第一行,其中有多个列定义该组
下面是一个虚拟表,用于描述我尝试执行的操作:Sql 选择group by中的第一行,其中有多个列定义该组,sql,postgresql,greatest-n-per-group,Sql,Postgresql,Greatest N Per Group,下面是一个虚拟表,用于描述我尝试执行的操作: ID_1 | ID_2 | ID_3 | Day | Energy_Costs | ----------+----------+------------+-------+---------------+ State_1 | County_1 | Building_1 | 1 | 48.8 | State_1 | County_1 | Building_1 | 2 | 31.
ID_1 | ID_2 | ID_3 | Day | Energy_Costs |
----------+----------+------------+-------+---------------+
State_1 | County_1 | Building_1 | 1 | 48.8 |
State_1 | County_1 | Building_1 | 2 | 31.3 |
State_1 | County_1 | Building_2 | 1 | 20.5 |
State_1 | County_2 | Building_1 | 1 | 1.9 |
State_2 | County_1 | Building_1 | 1 | 6.6 |
State_2 | County_2 | Building_2 | 1 | 38.2 |
State_2 | County_2 | Building_2 | 2 | 12.0 |
在上表中,唯一记录(本例中为建筑)需要3列(ID_1、ID_2、ID_3)。我想返回一个给定日期第一行的桌子
以下是我脑海中的查询:
SELECT FIRST(ID_1), FIRST(ID_2), FIRST(ID_3), FIRST(Energy_Costs), FIRST(DAY)
FROM buildings_db
GROUP BY ID_1, ID_2, ID_3
ORDER BY DAY
这将返回:
ID_1 | ID_2 | ID_3 | Day | Energy_Costs |
----------+----------+------------+-------+---------------+
State_1 | County_1 | Building_1 | 1 | 48.8 |
State_1 | County_1 | Building_2 | 1 | 20.5 |
State_1 | County_2 | Building_1 | 1 | 1.9 |
State_2 | County_1 | Building_1 | 1 | 6.6 |
State_2 | County_2 | Building_1 | 1 | 38.2 |
我见过其他问题问类似的问题,但它们通常没有定义一个组的多个列。我对SQL非常陌生,因此将它们转换为我的示例是不成功的;如果你们中的任何一位能够解释解决方案工作的原因,这将非常有帮助。您可以使用
DISTINCT ON()
。它适用于任意数量的列来定义组:
SELECT DISTINCT ON (ID_1, ID_2, ID_3)
ID_1, ID_2, ID_3, DAY, Energy_Costs
FROM buildings_db
ORDER BY ID_1, ID_2, ID_3, DAY, Energy_Costs;
这将返回(ID\u 1,ID\u 2,ID\u 3)
的每个不同组合的第一行,第一行由附加的ORDER by
表达式定义
得到
建筑物给定日期的第一行:
详细说明:
连接
select b.ID_1, b.ID_2, b.ID_3, b.Energy_Costs, b.DAY
from buildings_db b
join
(
select ID_1, ID_2, ID_3, min(day) min_day
from buildings_db
group by ID_1, ID_2, ID_3
) t on b.id_1 = t.id_1 and
b.id_2 = t.id_2 and
b.id_2 = t.id_2 and
b.day = t.min_day
欧文,你的回答非常有帮助!你已经正确地回答了这个问题,但我意识到我没有创建足够准确的表示。还有一种味道:我的数据不是“天”,而是时间序列。我想返回时间的最早实例,但我不能可靠地将其作为一个实例来表示。您在示例中所做的事情是否有一种动态的方式?比如:“Where Day=minimum(Day)”@MattM:如果你意识到你还有另一个不同的问题,那就开始一个新问题(有明确的细节)。评论不是地方。
select b.ID_1, b.ID_2, b.ID_3, b.Energy_Costs, b.DAY
from buildings_db b
join
(
select ID_1, ID_2, ID_3, min(day) min_day
from buildings_db
group by ID_1, ID_2, ID_3
) t on b.id_1 = t.id_1 and
b.id_2 = t.id_2 and
b.id_2 = t.id_2 and
b.day = t.min_day