2017-08-22 16 views
1

下のオラクルロジックをハイブに変換したいと思います。 ロジック:ハイブのデータ範囲に左結合を実装する方法

Select a.id,a.name,b.desc from table a left join table b on 
a.num between b.min_num and b.max_num; 

は、いずれかがハイブの上記のロジックを実現するために私を助けることができます。あなたは、パフォーマンス上のコントロールを持ってこのソリューションでは

+0

あなたはそれを行うことはできません。 MRは、等結合以外の外部結合に対しては何もサポートできません。あなたが参加することが他にあれば、レンジピースをwhere句に移動してヌルテストを試してみることができます。 – Andrew

+0

@Andrew - 私は少なくとも2つの方法でそれをすると思うことができます –

答えて

0
select a.id 
     ,a.name 
     ,b.desc 

from    table_a as a 

     left join (select a.id 
          ,b.desc 

        from    table_a as a 
          cross join table_b as b 

        where a.num between b.min_num and b.max_num 
        ) b      

     on   b.id = 
        a.id 
; 
+0

はい、クロス結合はうまくいくでしょうが、それは良い考えにはなりません。また、OPには作業するためのIDがあると仮定していますが、元のクエリでは表示されません。 – Andrew

+0

@Andrew - **(1)** CROSS JOINはデータの人口統計に依存して良いかどうかの選択肢です。 **(2)** 'a.id'は' a'のIDではないと仮定しますか? –

+0

ソリューションのおかげでマルコビッツ。 a.idはテーブルaのキーフィールドです。テーブルaに1mレコード、テーブルbに1kレコードがあるとクエリのパフォーマンスはどうですか? – ssk

0
select a.id 
     ,a.name 
     ,b.desc 

from    table_a as a 

     left join (select b.min_num + pe.pos as num 
          ,b.desc 

        from table_b as b 
           lateral view 
            posexplode(split(space(b.max_num-b.min_num),' ')) pe 
        ) b      

     on   b.num = 
        a.num 
; 
+0

@DudeMarkovitz、私は確かに上記のロジックについては確信していません、可能であれば、ロジックを記述することはできますか? 3つ目のソリューションに感謝します。 – ssk

+0

@sskでは、各[[min_num、max_num]]の範囲内で値を作成します。例えば。 'min_num' = 7、' max_num' = 11の場合、7,8,9,10,11の5つのレコードが作成されます。 –

1


b範囲はサブ範囲に分割されていて、希望通りに小さくなります(x)。

  • あまりにも大きいxは、実質的にクロスジョインを引き起こします。
  • 小さすぎるxは、bx = 1はすべてbの範囲の値を生成します)から大きなセットを生成する可能性があります。

set hivevar:x=100; 

select a.id 
     ,a.name 
     ,b.desc 

from  table_a as a 

     left join 

      (select a.id 
        ,b.desc 

      from  table_a as a 

        inner join 

         (select b.min_num div ${hivevar:x} + pe.pos as sub_range_id 
           ,b.* 

         from  table_b as b 
           lateral view 
            posexplode(split(space(cast (b.max_num div ${hivevar:x} - b.min_num div ${hivevar:x} as int)),' ')) pe 
         ) as b 

        on   a.num div ${hivevar:x} = 
           b.sub_range_id 

      where a.num between b.min_num and b.max_num 
      ) b      

     on   b.id = 
        a.id 
; 
+0

第3の解決策@Dudeに感謝します。 hqlのパフォーマンスを最適化するとより効果的です。 – ssk

関連する問題