0.背景
在使用Hive的時候有時候會遇到需要將一行“拆分”成多行的操作,如下。
原始數據格式,表名爲student_table
class student_array
1 [Tom,Jone]
2 [Lily,lucy]
目標數據格式
class student_name
1 Tom
1 Jone
2 Lily
2 Lucy
1.做法
先上做法,如下:
SELECT class, student_name
FROM student_table LATERAL VIEW explode(student_array) tableAlias as student_name
2.解釋
explode:首先我們知道UDF是user-defined function,例如concat(),都是輸入一行輸出一行。UDTF是 user-defined table-generating functions,相比較來說它們是輸入一行輸出多行,典型的就是explode()方法。https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-Built-inTable-GeneratingFunctions(UDTF)
LATERAL VIEW:側視表,用來連接UDTF(比如explode)產生的結果。如上所述,UTDF對每一行可以產生0行或者更多行,側視表可以把這個結果join到原始表上,然後起一個別名。1中tableAlias即表別名。
基本語法
lateralView: LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)*
fromClause: FROM baseTable (lateralView)*
3.進階
MULtiple LATERAL
VIEW。多重側視表,生成表的順序和sql中寫的順序有關。在下例中,交換兩行表中數據順序是不一樣的。
數據如下:
col1 col2
[1, 2] [a", "b", "c"]
[3, 4] [d", "e", "f"]
SELECT myCol1, myCol2 FROM baseTable
LATERAL VIEW explode(col1) myTable1 AS myCol1
LATERAL VIEW explode(col2) myTable2 AS myCol2;
OUTER參數
UDTF不同於UDF肯定有一行輸出(哪怕是NULL),在有些情況下可能輸出0行(典型的情況就是explode的列有空值),這樣的話source row也不會再表中出現,有時候這並不是我們希望的,可以在sql中添加OUTER參數,相當於我們將原始表和explode的結果做OUTER JOIN,避免source row完全丟失的情況。
SELECT * FROM src LATERAL VIEW OUTER explode(array()) C AS a limit 10
4.參考
1.https://cwiki.apache.org/confluence/display/Hive/LanguageManual+LateralView