2017-07-14 69 views
0

我想兩個DataFrames具有相同的架構比較(以星火1.6.0,使用Scala的),以確定哪些已經被添加的較新的錶行(即是不在舊錶中)。由一個ID列減去DataFrames - 重複列不同的表現

我需要通過ID來做到這一點(即檢查單個列,而不是整行,以查看什麼是新的)。某些行可能已更改版本之間,因爲它們具有相同的ID兩個版本,但其他列已經改變 - 我不輸出想要這些,所以我不能簡單地減去兩個版本。

基於各種建議,我在選定的ID列上進行左外連接,然後從連接的右側選擇列中有空值的行(表示它們不存在於舊版本的表):

def diffBy(field:String, newer:DataFrame, older:DataFrame): DataFrame = { 
    newer.join(older, newer(field) === older(field), "left_outer") 
     .select(older(field).isNull) 
     // TODO just select the leftmost columns, removing the nulls 
} 

但是,這是行不通的。 (第3行只存在於較新的版本,所以應該是輸出):

scala> newer.show 
+---+-------+ 
| id| value| 
+---+-------+ 
| 3| three| 
| 2|two-new| 
+---+-------+ 

scala> older.show 
+---+-------+ 
| id| value| 
+---+-------+ 
| 1| one| 
| 2|two-old| 
+---+-------+ 

scala> diffBy("id", newer, older).show 
+---+-----+---+-----+ 
| id|value| id|value| 
+---+-----+---+-----+ 
+---+-----+---+-----+ 

的加入正按預期:

scala> val joined = newer.join(older, newer("id") === older("id"), "left_outer") 
scala> joined.show 
+---+-------+----+-------+ 
| id| value| id| value| 
+---+-------+----+-------+ 
| 2|two-new| 2|two-old| 
| 3| three|null| null| 
+---+-------+----+-------+ 

所以問題是在過濾列的選擇。

joined.where(older("id").isNull).show 
+---+-----+---+-----+ 
| id|value| id|value| 
+---+-----+---+-----+ 
+---+-----+---+-----+ 

也許是由於連接中的重複id列名?但是,如果我使用value列(也複製),而不是檢測空值,它按預期工作:

joined.where(older("value").isNull).show 
+---+-----+----+-----+ 
| id|value| id|value| 
+---+-----+----+-----+ 
| 3|three|null| null| 
+---+-----+----+-----+ 

這到底是怎麼回事 - 爲什麼是idvalue不同的行爲?

回答

0

我已經找到了解決我的問題,雖然不是它爲什麼發生的解釋。

這似乎是必要的,以便明確地指到最右邊的id列創建別名,然後使用文本WHERE條款,這樣我可以在限定的列名從變量field替代:

newer.join(older.as("o"), newer(field) === older(field), "left_outer") 
    .where(s"o.$field IS NULL")