web-dev-qa-db-de.com

Hive: Summe über eine bestimmte Gruppe (HiveQL)

Ich habe einen Tisch:

key    product_code    cost
1      UK              20
1      US              10
1      EU              5
2      UK              3
2      EU              6

Ich möchte die Summe aller Produkte für jede Gruppe von "Schlüssel" ermitteln und an jede Zeile anhängen. Zum Beispiel für Schlüssel = 1, suchen Sie die Summe der Kosten aller Produkte (20 + 10 + 5 = 35) und hängen Sie dann das Ergebnis an alle Zeilen an, die dem Schlüssel = 1 entsprechen. Endergebnis:

key    product_code    cost     total_costs
1      UK              20       35
1      US              10       35
1      EU              5        35
2      UK              3        9
2      EU              6        9

Ich würde es vorziehen, dies ohne Sub-Join zu tun, da dies ineffizient wäre. Meine beste Idee wäre, die Funktion over in Verbindung mit der Funktion sum zu verwenden, aber ich kann sie nicht zum Laufen bringen. Mein bester Versuch:

SELECT key, product_code, sum(costs) over(PARTITION BY key)
FROM test
GROUP BY key, product_code;

Iv warf einen Blick auf die docs , aber da es so kryptisch ist, habe ich keine Ahnung, wie ich es herausfinden soll. Ich benutze Hive v0.12.0, HDP v2.0.6, HortonWorks Hadoop-Distribution.

9
joshlk

Verwenden Sie ähnlich der @VB_-Antwort die BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWINGAnweisung .

Die HiveQL-Abfrage lautet daher:

SELECT key, product_code,
SUM(costs) OVER (PARTITION BY key ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM test;
8
joshlk

Sie können BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW verwenden, um dies ohne Selbstverbindung zu erreichen.

Code wie folgt:

SELECT a, SUM(b) OVER (PARTITION BY c ORDER BY d ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM T;
4
VB_

Die Analytics-Funktionssumme ergibt kumulative Summen. Wenn Sie beispielsweise Folgendes getan haben:

select key, product_code, cost, sum(cost) over (partition by key) as total_costs from test

dann würden Sie bekommen:

key    product_code    cost     total_costs
1      UK              20       20
1      US              10       30
1      EU              5        35
2      UK              3        3
2      EU              6        9

was, wie es scheint, nicht das ist, was Sie wollen.

Verwenden Sie stattdessen die Aggregationsfunktionssumme in Kombination mit einem Self-Join, um dies zu erreichen:

select test.key, test.product_code, test.cost, agg.total_cost
from (
  select key, sum(cost) as total_cost
  from test
  group by key
) agg
join test
on agg.key = test.key;
2
Joe K

Diese Abfrage liefert mir ein perfektes Ergebnis

select key, product_code, cost, sum(cost) over (partition by key) as total_costs from zone;

1
Ashish Mohan

Der Tisch oben sah aus

key    product_code    cost
1      UK              20
1      US              10
1      EU              5
2      UK              3
2      EU              6

Der Benutzer wollte eine Tabelle mit den Gesamtkosten wie folgt

key    product_code    cost     total_costs
1      UK              20       35
1      US              10       35
1      EU              5        35
2      UK              3        9
2      EU              6        9

Dafür haben wir die folgende Abfrage verwendet

SELECT key, product_code,
SUM(costs) OVER (PARTITION BY key ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM test;

So weit, ist es gut. Ich möchte eine Kolumne mehr und zähle die Vorkommen jedes Landes

key    product_code    cost     total_costs     occurences
1      UK              20       35              2
1      US              10       35              1
1      EU              5        35              2
2      UK              3        9               2
2      EU              6        9               2

Dafür habe ich die folgende Abfrage verwendet

SELECT key, product_code,
SUM(costs) OVER (PARTITION BY key ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as total_costs
COUNT(product code) OVER (PARTITION BY key ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as occurences
FROM test;

Leider funktioniert das nicht. Ich bekomme einen kryptischen Fehler. Um einen Fehler in meiner Abfrage auszuschließen, möchte ich fragen, ob ich etwas falsch gemacht habe

1
Peter

ähnliche Antwort (wenn wir Oracle emp table verwenden):

select deptno, ename, sal, sum(sal) over(partition by deptno) from emp;

die Ausgabe wird wie folgt aussehen:

deptno  ename   sal sum_window_0
10  MILLER  1300    8750
10  KING    5000    8750
10  CLARK   2450    8750
20  SCOTT   3000    10875
20  FORD    3000    10875
20  ADAMS   1100    10875
20  JONES   2975    10875
20  SMITH   800     10875
30  BLAKE   2850    9400
30  MARTIN  1250    9400
30  ALLEN   1600    9400
30  WARD    1250    9400
30  TURNER  1500    9400
30  JAMES   950     9400
0
Pala