2017-03-17 174 views
0

我有查詢結果/表與列:id,日期。像:firebird 2.5選擇日期最近的日期記錄

ID,日期
0001,2012年1月20日
0001,2014年10月12日
0001,空
0001,2017年5月21日
0001,2017年8月15日
0002,空
技術,2013年6月5日
0002,2017年8月11日
0003,空
0004,2011年12月25日
0005,2017年12月10日
0006,null
0006,2013.04.23



etc ...
這是一個例子 - 在現實世界中,有幾千個id和超過一百五十萬條記錄。如何查找與今日日期最近的記錄(編號爲0001,0002,0005),以及只有空(0003),過去日期(編號0004)或空值和過去日期(編號0006)的記錄替換爲某些文本。結果應該是這樣的:

ID,日期
0001,2017年5月21日
0002,2017年8月11日
0003, '替換文本'
0004, '替換文本'
0005,2017年12月10日
0006,'替換文本'


等...
我希望這個例子顯示我所需要的。
謝謝你的任何線索。

+1

SO不是me'的服務的「代碼。你有什麼嘗試,你卡在哪裏? –

回答

1

似乎表中沒有主鍵。 請勿將字段名稱用作類型名稱,如「DATE」。

無論如何,這裏是一個例子如何做到你想要的,沒有聲稱它是最好的。

請注意,如果有很多記錄,此過程將會很慢,因此請確保放置了正確的索引。

SET TERM^; 

create or alter procedure TEMP_TEST_PROC (
    IDATE date) 
returns (
    OID varchar(4), 
    DATE_BEFORE date, 
    DATE_AFTER date, 
    CLOSEST_DATE date, 
    OTEXT varchar(32)) 
as 
begin 
    for select distinct id from test_table_wo_pk 
    into :oid 
    do 
    begin 
    date_before = null; 
    date_after = null; 
    /* get closest past date*/ 
    select first 1 t."DATE" from test_table_wo_pk t 
    where ((t."DATE" <= :idate) and (t.id = :oid)) 
    order by t."DATE" desc 
    into 
     :date_before; 

    /* get closest future date*/ 
    select first 1 t."DATE" from test_table_wo_pk t 
    where (t."DATE" >= :idate) and (t.id = :oid) 
    order by t."DATE" 
    into 
     :date_after; 

    /* bonus - get closest future or past date */ 

    ... You may check date_before, date_after for NULL here, and set closest_date value here.... 

    if ((datediff(day,:date_before,:idate)) < (datediff(day,:idate,date_after))) then 
     closest_date = :date_before; 
    else 
     closest_date = :date_after; 

    /* set text column */ 
    if (:date_after is not null) then 
     otext = :date_after; 
    else 
     otext = 'replased text'; 
    suspend; 
    end 
end^ 

SET TERM ;^

其結果是:

enter image description here

+0

它的工作原理。這是非常緩慢的,但我有起點繼續....感謝瓦爾。 – jirzinek