【问题标题】:Constructing an Oracle SQL query构建 Oracle SQL 查询
【发布时间】:2018-08-15 13:43:12
【问题描述】:

给定一个像这样的数据表:

+-----+-------------+--------+
| id  | end         | status |
+-----+-------------+--------+
| a   | 07-FEB-2018 | 1      |
| a   | 08-FEB-2018 | 2      |
| a   | 08-FEB-2018 | 3      |
| b   | 06-MAR-2018 | 2      |
| b   | 08-SEP-2018 | 3      |
+-----+-------------+--------+

在 Oracle SQL 中,可以构造一个查询,该查询将为每个 id 返回最大结束日期的最小状态(可能有多个行具有相同的最大结束日期)。

所以在这个例子中,这将被返回:

+-----+--------+
| id  | status |
+-----+--------+
| a   | 2      |
| b   | 3      |
+-----+--------+

我一直在查看 FIRST_VALUE 和 PARTITION BY,但我很难理解它们是如何工作的,以及它们是否是我所需要的,因此我并没有真正得到任何结果。

任何帮助将不胜感激!

【问题讨论】:

  • 为表明问题的问题提供适当的标题。 “构造查询”太笼统了。
  • 如果你能推荐一个更好的标题,我会很乐意改变它(如果可以的话)。部分问题是不知道我正在尝试做的事情的技术名称

标签: sql oracle greatest-n-per-group


【解决方案1】:

你可以使用最大端的内连接

select m.id, min(m.status)
from my_table m
inner join ( 
select id, max(end) max_end
from my_table  
group by id ) t.max_end = m.end   and t.id = m.id 
group by m.id 

【讨论】:

    【解决方案2】:

    一种方法使用row_number():

    select t.*
    from (select t.*,
                 row_number() over (partition by id order by end desc, status asc) as seqnum
          from t
         ) t
    where seqnum = 1;
    

    您也可以使用聚合函数来做到这一点:

    select id,
           min(status) keep (dense_rank first order by date desc, status asc) as status
    from t
    group by id;
    

    【讨论】:

    • 您不需要在min ... keep 查询中按status 订购,因为min(status) 部分已经在执行相同的功能。
    • 谢谢!我选择了第二个选项,这是一种享受
    猜你喜欢
    • 2021-10-26
    • 2015-12-02
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多