2015-06-30 168 views
1

從最後非空值填充空值我有4列在蜂巢

date number Estimate Client  
---- ------ 
1  3   10  A 
2  NULL  10  Null 
3  5   10  A  
4  NULL  10  Null 
5  NULL  10  Null 
6  2   10  A 
....... 

我需要用新的值替換NULL值取從最後已知值值在以前的日期在日期列例如:日期= 2號碼= 3,日期4和5號碼= 5和5.空值隨機出現。

這需要在Hive中完成。

回答

1

這是一個使用標準hiveql連接的解決方案。這應該適用於所有版本的配置單元。表c合併非空的客戶端的最近日期。後面的表格d合併與該日期相關的號碼。只有當數字爲空時才使用附加值。

select c.date 
, coalesce(c.number,d.number) as number 
, c.client 
, estimate 
from 
    (select date 
    , max(prior_date) as prior_date -- nearest date not null number 
    , value 
    , estimate 
    , a.client 
    from 
     (select date 
      , value 
      , estimate 
      , client 
      from table_have 
     ) a 
     left outer join 
     (select date as prior_date -- dates without nulls 
      , client 
      from table_have 
      where number is not null 
     ) b 
     on a.client=b.client 
     where date > prior_dates 
     group by a.client, date, value 
    ) c 
left outer join 
    (select date 
    , number 
    , client 
    from table_have 
    where number is not null 
) d 
    on c.client = d.client and c.prior_date=d.date 
    group by c.date, c.client, estimate 
; 

通過使用類似於備用解決方案中使用的通用表表達式,可以更好地優化此查詢。但是,這種解決方案不需要N次重複線路,並且應該普遍工作。另一種解決方案所需的數量N可能不是靜態的,因爲這種解決方案可能適用於更一般的情況。

+0

我解決了這個問題嗎?如果這樣你能接受答案,那麼社區可以看到存在問題的解決方案。 – invoketheshell

0

這實際上是一個非常棘手的問題,因爲Hive不支持遞歸CTE或相關子查詢,這將是解決此類問題的常用方法。

我能想到的唯一的純Hive方式就是做一堆自我連接。您必須執行與數據中連續空值的最大長度一樣多的操作。

--add in row numbers 
with T as 
(select select *, row_number() over (order by date) rn 
from mytable) 
--main query 
select T.date, 
     case when T.number is not null then T.number 
     else when T1.number is not null then T1.number 
     else when T2.number is not null then T2.number end as number 
     --repeat this N times 
     --where N is the length of the longest sequece of consectutive nulls 

     -- add in your other columns here 
from T 
join T T1 on T1.date = t.date - 1 
join T T2 on T2.date = t.date - 2 
--repeat this N times 
+0

我們有大約100萬條記錄,並且無法預測將會有多少個空值,因此這不是解決方案 – Peter2711

3

這是關於推拉窗;

這是我的表格內容;

hive> select * from my_table; 
OK 
1  3  10  A 
2  NULL 10  NULL 
3  5  10  A 
4  NULL 10  NULL 
5  NULL 10  NULL 
6  2  10  A 
Time taken: 0.06 seconds, Fetched: 6 row(s) 

所有你需要做的就是滑過前一個窗口和當前行之間的窗口並找到最近的非空值。 LAST_VALUE windowable函數有一個參數來忽略空值作爲布爾值。 LAST_VALUE(<field>,<ignore_nulls> as boolean);

SELECT 
    COALESCE(`date`, LAST_VALUE(`date`, TRUE) OVER(ORDER BY `date` ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)), 
    COALESCE(number, LAST_VALUE(number, TRUE) OVER(ORDER BY `date` ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)), 
    COALESCE(estimate, LAST_VALUE(estimate, TRUE) OVER(ORDER BY `date` ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)), 
    COALESCE(client, LAST_VALUE(client, TRUE) OVER(ORDER BY `date` ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) 
FROM my_table; 

結果是;

OK 
1  3  10  A 
2  3  10  A 
3  5  10  A 
4  5  10  A 
5  5  10  A 
6  2  10  A 
Time taken: 19.177 seconds, Fetched: 6 row(s)