解決失敗: UDFArgumentExceptionexplode() は配列またはマップをパラメータとして受け取り、explode 関数と側面図を理解します。
一、解決失敗: UDFArgumentExceptionexplode() は配列またはマップをパラメータとして受け取ります
1. 背景
プロジェクトでデータ処理を行った結果、クエリから得られる結果はすべて以下の通りですジャンルフィールドの型は実際には文字列(ビジネスロジック処理の結果)であり、視覚的に表示すると配列のように見えます。
SELECT
get_json_object(map_col,'$.game_name') game_name,
get_json_object(map_col,'$.genre') genre
FROM
ods_crawler_table
WHERE
dt = '2023-02-26'
AND get_json_object(map_col,'$.code') = 'xxx'
2. 次に、explode関数を使用して、ジャンルフィールドの1行を複数行に変換します。
SELECT
explode(get_json_object(map_col,'$.genre')) genre
FROM
ods_crawler_table
WHERE
dt = '2023-02-26'
AND get_json_object(map_col,'$.code') = 'xxx'
3. エラーを報告する
エラー メッセージ: 失敗: UDFArgumentExceptionexplode() は配列またはマップをパラメータとして受け取ります
4. 理由を分析します。
①このジャンルは表面的には配列にしか見えないが、業務処理を行うと実はString型である
②そして冗長な[]がついたString型である
③配列型に加工する必要がある前提として、最初に冗長な [] が削除され、次に String の分割メソッドを使用して配列が返されます。
split(regexp_replace(get_json_object(map_col,'$.genre'), '\\[|\\]', ''), ",")
------------------------------------------------------------------------------------------------------------------
SELECT
split(regexp_replace(get_json_object(map_col,'$.genre'), '\\[|\\]', ''), ",") genre
FROM
ods_crawler_table
WHERE
dt = '2023-02-26'
AND get_json_object(map_col,'$.code') = 'xxx'
結果は次のとおりです。
爆発関数の爆発効果をもう一度試してください。
SELECT
explode(split(regexp_replace(get_json_object(map_col,'$.genre'), '\\[|\\]', ''), ",")) genre
FROM
ods_crawler_table
WHERE
dt = '2023-02-26'
AND get_json_object(map_col,'$.code') = 'xxx'
今のところ、爆発に成功しています~~~~~~~~~~~~~
5. 他のフィールドと一緒にexplode(genre)をクエリします。
- 実際のビジネスでは、フィールド game_name と ジャンルをクエリする必要があります。
SELECT
get_json_object(map_col,'$.game_name') game_name,
explode(split(regexp_replace(get_json_object(map_col,'$.genre'), '\\[|\\]', ''), ",")) genre
FROM
ods_crawler_table
WHERE
dt = '2023-02-26'
AND get_json_object(map_col,'$.code') = 'xxx'
エラーが報告されました:
- 情報: UDTF は SELECT 句の外側ではサポートされておらず、式内でネストされてもサポートされていません
分析: 理由は、このフィールド ジャンルが展開後に複数の列 (3 列) に変換されるのに対し、game_name フィールドはまだ 1 列であり、列数が一致しないためです。
解決策: 側面図 (テーブル) の集約
ods_crawler_table -- 原先的表
LATERAL VIEW -- 聚合(本质上就是笛卡尔乘积)
explode(split(regexp_replace(get_json_object(map_col,'$.genre'), '\\[|\\]', ''), ",")) v -- 炸裂后作为一个表,两个表聚合之后成v表
as genre -- 是炸裂函数explode(split(regexp_replace(get_json_object(map_col,'$.genre'), '\\[|\\]', ''), ","))的别名
------------------------------------------------------------------------------------------------------------------------
SELECT
get_json_object(map_col,'$.game_name') game_name,
genre
FROM
ods_crawler_table
LATERAL VIEW explode(split(regexp_replace(get_json_object(map_col,'$.genre'), '\\[|\\]', ''), ",")) v as genre
WHERE
dt = '2023-02-26'
AND get_json_object(map_col,'$.code') = 'xxx'
集約効果:
詳細: 側面図と分解を一緒に使用すると、2 つのエイリアスが存在します。
-
最初のエイリアスは 2 つのテーブル集計のエイリアスで、2 番目のエイリアスはバースト関数のエイリアスです。
-
文法
tableA LATERAL VIEW -- 聚合 explode(fieldB) v -- v 别名:tableA 和自身表使用了explode函数后得到的那个表,进行聚合后得到的新表 as b -- b 别名:explode函数使用后起的别名
2.バースト機能と側面図を理解する
1、爆発する :
(1) 機能: 1 行のデータを複数の列のデータに変換し、配列およびマップ型データに使用されます。
(2) 文法と例:
爆発(配列)
-- 炸裂字段array('A','B','C')
select explode(array('A','B','C')) as col;
コル |
---|
あ |
B |
C |
爆発(マップ)
-- 炸裂字段 map('A', 10, 'B',10, 'C',10)
select explode(map('A', 10, 'B',10, 'C',10)) as (key, value);
鍵 | 価値 |
---|---|
あ | 10 |
B | 20 |
C | 30 |
posexplode (配列)
select posexplode(array('A','B','C')) as (pos,val);
位置 | ヴァル |
---|---|
0 | あ |
1 | B |
2 | C |
(3) バースト機能のデメリット:
フィールドが展開されると、そのフィールドの列数がテーブル内の残りのフィールドと一致しなくなり、展開されたフィールドをテーブル内の他のフィールドと一緒にクエリできなくなります。
解決策: 側面図
2、側面図
(1) 機能: UDTF 関数だけでは選択列を追加できない問題を解決するために、UDTF と組み合わせて使用します。
側面図では、UDTF によって生成された結果が仮想テーブルに配置され、この仮想テーブルが入力行と結合されて、UDTF の外側の選択フィールドを接続するという目的を達成します。
(2) 文法と例:
□ 文法:
tableA
LATERAL VIEW -- 聚合
explode(fieldB) v -- v 别名:tableA 和自身表使用了explode函数后得到的那个表,进行聚合后得到的新表
as b -- b 别名:explode函数使用后起的别名
□例:
元のテーブル t クエリの結果は次のとおりです。
select festival,good_name from tableA;
祭り | いい名前 |
---|---|
端午節 | 端午節、端午節、崇武節 |
半ば秋祭り | 再会、月を拝む |
春祭り | 新年、新年、元旦 |
-- 使用explode 函数
select explode(good_name) as good_name from tableA;
いい名前 |
---|
端陽 |
ドラゴンボート |
崇武 |
再会 |
祭月 |
新年 |
新年 |
元旦 |
-
実現したい効果: フェスティバル名とエイリアスの集約 エクスプロード関数を使用する場合は、フィールド フェスティバルを直接クエリします。
会报错
select festival, explode(another_name) from tableA;
-
报错
: UDTF は、SELECT 句の外ではサポートされておらず、式内でネストされても、つまりエクスプロイト (UDTF) を意味するため、他のフィールドで直接使用することはできません。 -
解决
: 側面図を使用しますselect festival, good_name from tableA LATERAL VIEW explode(good_name) v as good_name;
-
効果:
祭り | 別の名前1 |
---|---|
端午節 | 端陽 |
端午節 | ドラゴンボート |
端午節 | 崇武 |
半ば秋祭り | 再会 |
半ば秋祭り | 祭月 |
春祭り | 新年 |
春祭り | 新年 |
春祭り | 元旦 |
この記事が役に立った場合は、忘れずに Yile に「いいね!」を押してください。ありがとうございます。