比较oracle中的行值

时间:2015-09-29 09:49:39

标签: sql oracle rank window-functions

我有Table1有三列:

 Key | Date   | Price
----------------------
 1   | 26-May | 2
 1   | 25-May | 2
 1   | 24-May | 2
 1   | 23 May | 3
 1   | 22 May | 4
 2   | 26-May | 2
 2   | 25-May | 2
 2   | 24-May | 2
 2   | 23 May | 3
 2   | 22 May | 4

我想选择上次更新值2的行(24-May)。日期使用RANK函数进行排序。 我无法获得理想的结果。任何帮助将不胜感激。

SELECT *
  FROM (SELECT key, DATE, price,
               RANK() over (partition BY key order by DATE DESC) AS r2 
          FROM Table1 ORDER BY DATE DESC) temp;

3 个答案:

答案 0 :(得分:1)

另一种查看问题的方法是,您希望找到价格与上次价格不同的最新记录。然后你想要下一条记录。

with lastprice as (
      select t.*
      from (select t.*
            from table1 t
            order by date desc
           ) t
      where rownum = 1
     )
select t.*
from (select t.*
      from table1 t
      where date > (select max(date)
                    from table1 t2
                    where t2.price <> (select price from lastprice)
                   )
     order by date asc
    ) t
where rownum = 1;

此查询看起来很复杂。但是,它的结构使它可以利用table1(date)上的索引。 Oracle 12之前的子查询是必需的。在最新版本中,您可以使用fetch first 1 row only

编辑:

另一种解决方案是使用lag()并找到值更改时的最近时间:

select t1.*
from (select t1.*
      from (select t1.*,
                   lag(price) over (order by date) as prev_price
            from table1 t1
           ) t1
      where prev_price is null or prev_price <> price
      order by date desc
     ) t1
where rownum = 1;

在许多情况下,我希望第一个版本具有更好的性能,因为在最里面的子查询中只有繁重的工作才能获得max(date)。本章必须计算lag()以及order by。但是,如果性能存在问题,则应测试环境中的数据。

编辑II:

我最好的猜测是你想要每key。您的原始问题没有说明key,但是:

select t1.*
from (select t1.*,
             row_number() over (partition by key order by date desc) as seqnum
      from (select t1.*,
                   lag(price) over (partition by key order by date) as prev_price
            from table1 t1
           ) t1
      where prev_price is null or prev_price <> price
      order by date desc
     ) t1
where seqnum = 1;

答案 1 :(得分:-1)

你可以试试这个: -

SELECT Date FROM Table1
WHERE Price = 2
AND PrimaryKey = (SELECT MAX(PrimaryKey) FROM Table1
                  WHERE Price = 2)

答案 2 :(得分:-1)

这与Gordon Linoff的第二个选项非常类似,但引入了第二个窗口函数row_number()来定位更改价格的最新行。这适用于所有或一系列键。

select
* 
from (
      select
            *
            , row_number() over(partition by Key order by [date] DESC) rn
      from (
            select
                *
                , NVL(lag(Price) over(partition by Key order by [date] DESC),0) prevPrice
            from table1
            where Key IN (1,2,3,4,5) -- as an example
           )
      where Price <> prevPrice
     )
where rn = 1
道歉,但我还没有能够对此进行测试。