簡體   English   中英

在oracle中比較行值

[英]Comparing row values in oracle

我有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;

解決問題的另一種方法是,您要查找價格與最新價格不同的最新記錄。 然后,您需要下一條記錄。

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 但是,如果性能成為問題,則應在環境中測試數據。

編輯二:

我最好的猜測是每個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;

您可以嘗試以下方法:

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

這與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

抱歉,我根本無法測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM