Oracle SQL:获取每个复杂组/分区的第一个值

时间:2015-11-26 16:40:29

标签: sql oracle oracle11g

如果使用SQL的Oracle,我可以在每个第一列A,B中检索一个表,以防B列更改由A ???排序的值

假设我有一张包含日期和值的表:

DATE;VALUE
01-2015;1
02-2015;1
01-2016;2
01-2016;2
01-2017:1

所以我现在想要的是,一旦值发生变化,每个第一行(基于DATE的某些顺序)所以从这个集合中我想要:

DATE;VALUE
01-2015;1 
01-2016;2 
01-2017:1

现在我不能使用简单的GROUP BY VALUE,因为该值可以再次翻转(在本例中为2015年和2017年的1),MIN(DATECOL)GROUP BY VALUECOL将不会报告2017年。

所以我正在研究分析函数:

SELECT FIRST_VALUE(DATECOL),FIRST_VALUE(VALUECOL) OVER (PARTITION BY
VALUECOL ORDER BY DATECOL) FROM DATATABLE 

但我不能让这个工作!

2 个答案:

答案 0 :(得分:2)

Tabibtosan让这一切变得简单:

with table1 as (select to_date('01/01/2015', 'dd/mm/yyyy') dt, 1 val from dual union all
                select to_date('01/02/2015', 'dd/mm/yyyy') dt, 1 val from dual union all
                select to_date('01/01/2016', 'dd/mm/yyyy') dt, 2 val from dual union all
                select to_date('01/01/2016', 'dd/mm/yyyy') dt, 2 val from dual union all
                select to_date('01/01/2017', 'dd/mm/yyyy') dt, 1 val from dual)
-- end of mimicking a table "table1" with data in it. See sql below:
select min(dt) dt,
       val
from   (select dt,
               val,
               dense_rank() over (order by dt)
                 - dense_rank() over (partition by val order by dt) grp
        from   table1)
group by val,
         grp;

DT                VAL
---------- ----------
01/01/2015          1
01/01/2016          2
01/01/2017          1

答案 1 :(得分:0)

我认为LAG()是适当的功能,还有其他一些逻辑:

select t.*
from (select t.*, lag(value) over (order by date) as prev_value
      from datatable t
     ) t
where prev_value is null or prev_value <> value;

您的数据唯一的问题是行不是唯一的。这可能会导致问题,因为数据库中的排序不稳定(即,两行可以按任意顺序排列)。希望在您的实际数据中,日期是唯一的,或者您可以添加另一个ID order by以使排序稳定。

这样做的一种蛮力方式是:

with dt as (
      select dt.*, rownum as rn
      from datatable dt
     )
select t.*
from (select dt.*, lag(value) over (order by date, rn) as prev_value
      from datatable dt
     ) t
where prev_value is null or prev_value <> value;