解決失敗: UDFArgumentExceptionexplode() は配列またはマップをパラメータとして受け取り、explode 関数と側面図を理解します。


解決失敗: 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 に「いいね!」を押してください。ありがとうございます。

おすすめ

転載: blog.csdn.net/weixin_45630258/article/details/129241233