获取以前的非空值

时间:2019-01-29 14:48:33

标签: sql oracle11g

我有一个利率表t0

示例:

id   code   dev   period   rate    
4937   TRY   EUR   201812   0.1649    
4940   AED   EUR   201812   0.2392    
4857   USD   EUR   201812   1.4259    
4845   CNY   EUR   201811   0.1678
4851   AED   EUR   201811   0.3949    
4960   AED   EUR   201810   1.1949
4886   TRY   EUR   201809   1.128    
4986   RSD   EUR   201808   1.006

我想从表t1的每个日期获取t0的费率

我尝试了last_value函数,但是它不起作用。您还有其他想法吗?

select t3.id
   ,t0.period
   ,t1.date 
   ,t0.code
   ,(CASE WHEN t0.period is null THEN last_value(t0.rate ignore nulls) OVER (order by t1.date ROWS BETWEEN  UNBOUNDED PRECEDING AND 1 PRECEDING) ELSE t0.rate END) as rate 
from t1
 INNER JOIN t2 ON t2.id = t1.id
 LEFT OUTER JOIN t3 ON t3.id  = t1.id3
 LEFT OUTER JOIN t0 ON t0.code = t1.code
                        AND  t0.period < to_char(t1.date, 'YYYYMM') 

所需结果:

情况0:

如果t0.period = to_char(t1.date,'YYYYMM'),那么我想得到一行

15|201812|201812|TRY|0.1649    
21|201808|201808|RSD|1.006

案例1:

如果t0.period为null,那么我搜索的最后一个速率不为null:

2|201812|201911|AED|0.2392    
45|201812|201910|USD|1.4259

2 个答案:

答案 0 :(得分:2)

您还可以通过内部联接和分析功能来实现此目标-例如:

WITH t0 AS (SELECT 4937 ID, 'TRY' CODE, 'EUR' dev, 201812 period, 0.1649 rate FROM dual UNION ALL
            SELECT 4940 ID, 'AED' CODE, 'EUR' dev, 201812 period, 0.2392 rate FROM dual UNION ALL
            SELECT 4857 ID, 'USD' CODE, 'EUR' dev, 201812 period, 1.4259 rate FROM dual UNION ALL
            SELECT 4845 ID, 'CNY' CODE, 'EUR' dev, 201811 period, 0.1678 rate FROM dual UNION ALL
            SELECT 4851 ID, 'AED' CODE, 'EUR' dev, 201811 period, 0.3949 rate FROM dual UNION ALL
            SELECT 4960 ID, 'AED' CODE, 'EUR' dev, 201810 period, 1.1949 rate FROM dual UNION ALL
            SELECT 4886 ID, 'TRY' CODE, 'EUR' dev, 201809 period, 1.128 rate FROM dual UNION ALL
            SELECT 4986 ID, 'RSD' CODE, 'EUR' dev, 201808 period, 1.006 rate FROM dual),
     t1 AS (SELECT 15 ID, 201812 dt, 'TRY' CODE FROM dual UNION ALL
            SELECT 21 ID, 201808 dt, 'RSD' CODE FROM dual UNION ALL
            SELECT 2 ID, 201911 dt, 'AED' CODE FROM dual UNION ALL
            SELECT 45 ID, 201910 dt, 'USD' CODE FROM dual)
SELECT ID,
       period,
       dt,
       CODE,
       rate
FROM   (
SELECT t1.id,
     t0.period,
     t1.dt,
     t1.code,
     t0.rate,
       MAX(t0.period) OVER (PARTITION BY t1.id) max_period-- assuming t1.id is the primary or unique key for t1
FROM   t0
       INNER JOIN t1 ON t0.period <= t1.dt AND t0.code = t1.code)
WHERE  period = max_period;

        ID     PERIOD         DT CODE       RATE
---------- ---------- ---------- ---- ----------
         2     201812     201911 AED      0.2392
        15     201812     201812 TRY      0.1649
        21     201808     201808 RSD       1.006
        45     201812     201910 USD      1.4259

如果我是你,我会检查哪个答案最适合您的数据和结构等。

答案 1 :(得分:1)

我认为您希望cross join生成行,然后希望left join引入值:

select cd.code, cd.dev, t1.date,
       coalesce(t0.rate, lag(t0.rate ignore nulls) over (partition by cd.code, cd.dev order by cd.date) as rate
from t1 cross join
     (select distinct code, dev from t0) cd left join
     t0
     on t0.period = t1.date and t0.code = cd.code and and t0.dev = t0.dev;