Lateral View Syntax
lateralView: LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)* fromClause: FROM baseTable (lateralView)*
Description
Lateral view is used in conjunction with user-defined table generating functions such as explode()
. As mentioned in Built-in Table-Generating Functions, a UDTF generates one or more output rows for each input row. A lateral view first applies the UDTF to each row of base table and then joins resulting output rows to the input rows to form a virtual table having the supplied table alias.
Version
Prior to Hive 0.6.0, lateral view did not support the predicate push-down optimization. In Hive 0.5.0 and earlier, if you used a WHERE clause your query may not have compiled. A workaround was to add set hive.optimize.ppd=false;
before your query. The fix was made in Hive 0.6.0; see https://issues.apache.org/jira/browse/HIVE-1056: Predicate push down does not work with UDTF's.
Example
Consider the following base table named pageAds
. It has two columns: pageid
(name of the page) and adid_list
(an array of ads appearing on the page):
Column name |
Column type |
---|---|
pageid |
STRING |
adid_list |
Array<int> |
An example table with two rows:
pageid |
adid_list |
||
---|---|---|---|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="e1d51d34-98b3-4ffc-8222-4b3d3b764c6e"><ac:plain-text-body><![CDATA[ |
front_page |
[1, 2, 3] |
]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="62938136-804a-438b-98eb-ec49c6717f42"><ac:plain-text-body><![CDATA[ |
contact_page |
[3, 4, 5] |
]]></ac:plain-text-body></ac:structured-macro> |
and the user would like to count the total number of times an ad appears across all pages.
A lateral view with explode() can be used to convert adid_list
into separate rows using the query:
SELECT pageid, adid FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid;
The resulting output will be
pageid (string) |
adid (int) |
---|---|
"front_page" |
1 |
"front_page" |
2 |
"front_page" |
3 |
"contact_page" |
3 |
"contact_page" |
4 |
"contact_page" |
5 |
Then in order to count the number of times a particular ad appears, count/group by can be used:
SELECT adid, count(1) FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid GROUP BY adid;
int adid |
count(1) |
1 |
1 |
2 |
1 |
3 |
2 |
4 |
1 |
5 |
1 |
Multiple Lateral Views
A FROM clause can have multiple LATERAL VIEW clauses. Subsequent LATERAL VIEWS can reference columns from any of the tables appearing to the left of the LATERAL VIEW.
For example, the following could be a valid query:
SELECT * FROM exampleTable LATERAL VIEW explode(col1) myTable1 AS myCol1 LATERAL VIEW explode(myCol1) myTable2 AS myCol2;
LATERAL VIEW clauses are applied in the order that they appear. For example with the following base table:
Array<int> col1 |
Array<string> col2 |
||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="b3d7c73a-1636-4b79-90eb-26d46e21b74d"><ac:plain-text-body><![CDATA[ |
[1, 2] |
[a", "b", "c"] |
]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0c61cbbd-f32c-4579-b1d0-c29c097172b5"><ac:plain-text-body><![CDATA[ |
[3, 4] |
[d", "e", "f"] |
]]></ac:plain-text-body></ac:structured-macro> |
The query:
SELECT myCol1, col2 FROM baseTable LATERAL VIEW explode(col1) myTable1 AS myCol1;
Will produce:
int mycol1 |
Array<string> col2 |
||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="3ec4f773-6a98-4b3e-9f3d-8041f7de3b30"><ac:plain-text-body><![CDATA[ |
1 |
[a", "b", "c"] |
]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="19291290-043f-403b-9e3d-41dfddbce108"><ac:plain-text-body><![CDATA[ |
2 |
[a", "b", "c"] |
]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="6a8c1633-43fb-4228-9144-a7106580091a"><ac:plain-text-body><![CDATA[ |
3 |
[d", "e", "f"] |
]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="edfb4577-2353-4bb8-bedc-066ca7ded8bd"><ac:plain-text-body><![CDATA[ |
4 |
[d", "e", "f"] |
]]></ac:plain-text-body></ac:structured-macro> |
A query that adds an additional LATERAL VIEW:
SELECT myCol1, myCol2 FROM baseTable LATERAL VIEW explode(col1) myTable1 AS myCol1 LATERAL VIEW explode(col2) myTable2 AS myCol2;
Will produce:
int myCol1 |
string myCol2 |
1 |
"a" |
1 |
"b" |
1 |
"c" |
2 |
"a" |
2 |
"b" |
2 |
"c" |
3 |
"d" |
3 |
"e" |
3 |
"f" |
4 |
"d" |
4 |
"e" |
4 |
"f" |
Outer Lateral Views
Version
Introduced in Hive version 0.12.0
User can specify optional OUTER keyword to make a row with NULL(s) for UDTF side in case the UDTF does not make any rows.
For example, the following query returns empty result:
select * from src LATERAL VIEW explode(array()) C AS a limit 10;
But with OUTER keyword,
select * from src LATERAL VIEW OUTER explode(array()) C AS a limit 10;
Will produce:
238 val_238 NULL
86 val_86 NULL
311 val_311 NULL
27 val_27 NULL
165 val_165 NULL
409 val_409 NULL
255 val_255 NULL
278 val_278 NULL
98 val_98 NULL
...