2017-03-17 127 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