根据group by中的条件获取id

时间:2018-06-12 21:21:16

标签: sql greatest-n-per-group

我正在尝试创建一个SQL查询来合并有相同日期的行。我的想法是根据最长的小时数来做这件事,这样我最终会得到每个日期最高小时数的相应ID。我一直试图用一个简单的组来做,但似乎不起作用,因为我只能在id列上放置一个聚合函数,因为它应该基于小时条件

+------+-------+--------------------------------------+
| id   | date           | hours                       |
+------+-------+--------------------------------------+
| 1    | 2012-01-01     | 37                          |
| 2    | 2012-01-01     | 10                          |
| 3    | 2012-01-01     | 5                           |
| 4    | 2012-01-02     | 37                          |
+------+-------+--------------------------------------+

期望的结果

+------+-------+--------------------------------------+
| id   | date           | hours                       |
+------+-------+--------------------------------------+
| 1    | 2012-01-01     | 37                          |
| 4    | 2012-01-02     | 37                          |
+------+-------+--------------------------------------+

3 个答案:

答案 0 :(得分:0)

以下是使用row_number的一种方法:

select id, dt, hours
from (
    select id, dt, hours, row_number() over (partition by dt order by hours desc) rn
    from yourtable
) t
where rn = 1

答案 1 :(得分:0)

如果您只想要一行 - 即使有关系 - 那么请使用row_number()

select t.*
from (select t.*, row_number() over (partition by date order by hours desc) as seqnum
      from t
     ) t
where seqnum = 1;

具有讽刺意味的是,Postgres和Oracle(原始标签)都有我认为更好的方法,但它们完全不同。

Postgres的:

select distinct on (date) t.*
from t
order by date, hours desc;

甲骨文:

select date, max(hours) as hours,
       max(id) keep (dense_rank first over order by hours desc) as id
from t
group by date;

答案 2 :(得分:0)

您可以将子查询与关联方法一起使用:

select t.*
from table t
where id = (select t1.id
            from table t1
            where t1.date = t.date
            order by t1.hours desc
            limit 1);

Oracle 中,您可以使用fetch first 1 row only中的subquery代替LIMIT子句。