簡體   English   中英

如果日期不是最后一行,則在Oracle中將日期設置為上個月的最后一天

[英]Set date to last day of previous month in Oracle if it's not the last row

SQL Fiddle上的整個設置: http ://sqlfiddle.com/#!4/1fd0e/5

我有一些包含人員編號,級別和級別日期范圍的數據,如下所示:

   PID        LVL START_DATE END_DATE

     1          1 01.01.14   19.03.14 
     1          2 20.03.14   15.08.14 
     1          3 16.08.14   09.10.14 
     1          4 10.10.14   31.12.14 
     2          1 01.01.14   31.12.14 
     3          1 01.01.14   16.01.14 

我需要將開始日期設置為每月的第一天,將結束日期設置為每月的最后一天。 最后一天規則僅適用於該人的最后一行數據

到目前為止我所做的:

select
pid, lvl, 
trunc(start_date, 'month') as start_date,
case when lead(pid, 1) over (PARTITION BY pid order by end_date) is not null 
     then last_day(add_months(end_date, -1)) 
     else last_day(end_date) 
     end as end_date
from date_tbl t;

給我想要的輸出:

   PID        LVL START_DATE END_DATE

     1          1 01.01.14   28.02.14 
     1          2 01.03.14   31.07.14 
     1          3 01.08.14   30.09.14 
     1          4 01.10.14   31.12.14 
     2          1 01.01.14   31.12.14 
     3          1 01.01.14   31.01.14 

但是:它與我的測試數據配合得很好。 在我的包含25k +數據行的表上的生產數據上(執行權不是很多數據),它的執行速度非常慢。

誰能給我一個提示,說明如何提高查詢性能? 例如,要在夾心列上設置哪些索引? 到目前為止,唯一的索引列是PID列。

實際上,據我了解,如果某人只有一條記錄(pid = 3的情況),您的腳本將產生錯誤的結果

拜托,你可以試試這個嗎?

select
  pid, 
  lvl, 
  trunc(start_date, 'month') as start_date,
  last_day(add_months(end_date, case when lvl = max(lvl) over (partition by pid) then 0 else -1 end)) end_date
from date_tbl t;

我猜您需要為列建立索引(pid,lvl desc)

好的,很抱歉浪費您的時間。 簡而言之:這是我的錯。 在我的過程中,上面的查詢在某個子查詢中向另一個表進行了LEFT JOIN:

with dates as (
  select
  pid, lvl, 
  trunc(start_date, 'month') as start_date,
  case when lead(pid, 1) over (PARTITION BY pid order by end_date) is not null 
       then last_day(add_months(end_date, -1)) 
       else last_day(end_date) 
       end as end_date
  from date_tbl t
),
  some_other_table as (
  select pid, (...some more columns)
  from other_table
)
select * from (
  select 
    b.pid,  -- <== this has to be a.pid. b is much bigger than a!
    a.start_date, 
    a.end_date
  from dates a left join some_other_table b on a.pid = b.pid
)

整個查詢要大得多。

@jonearles thx您的評論。 “什么是完整查詢?” 幫助我重回正軌:將查詢拆分為多個部分,然后再次檢查是什么真正降低了它的速度。

暫無
暫無

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

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