5

私はハイブの初心者であり、以下の内容について事前に無知を許したいと思います. 次のようなテーブルがあります。

SELECT a.storeid, a.smonth, a.sales FROM table a;
1001    1       35000.0
1002    2       35000.0
1001    2       25000.0
1002    3       110000.0
1001    3       40000.0
1002    1       40000.0

私の客観的な出力は次のとおりです。

1001    1       35000.0 35000.0
1001    2       25000.0 60000.0
1001    3       40000.0 100000.0
1002    1       40000.0 40000.0
1002    2       35000.0 75000.0
1002    3       110000.0 185000.0

上記を達成するために単純なハイブ udf sum クラスを作成し、クエリで SORT BY storeid, smonth を使用しました。

SELECT a.storeid, a.smonth, a.sales, rsum(sales)
FROM (SELECT * FROM table SORT BY storeid, smonth) a;

明らかに、マッパーは 1 つしかなく、同じ udf インスタンスが呼び出されてセット全体の実行中の合計が生成されるため、上記の出力は生成されません。私の目的は、評価関数が上記の出力を返すように、各 storeid の udf クラスの runningSum インスタンス変数をリセットすることです。私は以下を使用しました: 1. storeid 変数 rsum(sales, storeid) を渡すと、udf クラスで状況を正しく処理できます。2. 次のクエリのように 2 つのマッパーを使用します。

set mapred.reduce.tasks=2;
SELECT a.storeid, a.smonth, a.sales, rsum(sales)
FROM (SELECT * FROM table DISTRIBUTE BY storeid SORT BY storeid, smonth) a;

1002    1       40000.0 40000.0
1002    2       35000.0 75000.0
1002    3       110000.0 185000.0
1001    1       35000.0 35000.0
1001    2       25000.0 60000.0
1001    3       40000.0 100000.0

1002 が常に一番上に表示されるのはなぜですか? 上記の方法とは別に、同じことを達成できる他の方法(サブクエリ/結合など)について提案を求めたいと思います。また、提案された方法の時間の複雑さはどうなりますか?

4

4 に答える 4

9

Hive は、これを 1 行で実行するためのより良い方法を提供し
ます。以下のプロセスに従って、目標の出力を達成してください。

データセットを含めることができるハイブテーブルを作成します -

1001    1       35000.0
1002    2       35000.0
1001    2       25000.0
1002    3       110000.0
1001    3       40000.0
1002    1       40000.0

ハイブターミナルで以下のコマンドを実行するだけです-

SELECT storeid, smonth, sales, SUM(sales) OVER (PARTITION BY storeid ORDER BY smonth) FROM table_name;

出力は次のようになります-

1001  1  35000.0  35000.0
1001  2  25000.0  60000.0
1001  3  40000.0  100000.0
1002  1  40000.0  40000.0
1002  2  35000.0  75000.0
1002  3  110000.0 185000.0

これが目標の出力を得るのに役立つことを願っています。

于 2015-01-19T12:54:52.800 に答える
4

または、いくつかの機能拡張を含むこのHive チケットを確認することもできます。
とりわけ、累積合計の実装 ( GenericUDFSum ) があります。

この関数 (「rsum」と呼ばれます) は 2 つの引数を取ります。id のハッシュ (レデューサー間でレコードが分割されます) と、合計される対応する値です。

select t.storeid, t.smonth, t.sales, rsum(hash(t.storeid),t.sales) as sales_sum 
  from (select storeid, smonth, sales from sm distribute by hash(storeid) 
    sort by storeid, smonth) t;

1001  1  35000.0  35000.0
1001  2  25000.0  60000.0
1001  3  40000.0  100000.0
1002  1  40000.0  40000.0
1002  2  35000.0  75000.0
1002  3  110000.0 185000.0
于 2013-01-29T16:28:17.083 に答える