2013-12-17 3 views
6

Ich bin neu in Hive/SQL, und ich bin auf ein ziemlich einfaches Problem fest. Meine Daten wie folgt aussehen:Zeile mit maximalem Wert in Hive/SQL erhalten?

+------------+--------------------+-----------------------+ 
| carrier_iD |  meandelay  |  meancanceled  | 
+------------+--------------------+-----------------------+ 
| EV   | 13.795802119653473 | 0.028584251044292006 | 
| VX   | 0.450591016548463 | 2.364066193853424E-4 | 
| F9   | 10.898001378359766 | 0.00206753962784287 | 
| AS   | 0.5071547420965062 | 0.0057404326123128135 | 
| HA   | 1.2031093279839498 | 5.015045135406214E-4 | 
| 9E   | 8.147899230704216 | 0.03876067292247866 | 
| B6   | 9.45383857757506 | 0.003162096314343487 | 
| UA   | 8.101511665305816 | 0.005467725574605967 | 
| FL   | 0.7265068895709532 | 0.0041141513746490044 | 
| WN   | 7.156119279121648 | 0.0057419058192869415 | 
| DL   | 4.206288692245839 | 0.005123990066804269 | 
| YV   | 6.316802855264404 | 0.029304029304029346 | 
| US   | 3.2221527095063736 | 0.007984031936127766 | 
| OO   | 6.954715814690328 | 0.02596499362466706 | 
| MQ   | 9.74568222216328 | 0.025628100708354324 | 
| AA   | 8.720522654298968 | 0.019242775597574157 | 
+------------+--------------------+-----------------------+ 

I Hive will die Zeile mit dem meanDelay Maximalwert zurückzukehren. Ich habe:

die tatsächlich die max zurückgibt (ich benutze Cast, weil meine Werte als STRING gespeichert sind). Also dann:

SELECT * FROM flightinfo WHERE meandelay = (SELECT CAST(MAX(meandelay) AS FLOAT) FROM flightinfo); 

Ich erhalte die folgende Fehlermeldung:

FAILED: ParseException line 1:44 cannot recognize input near 'select' 'cast' '(' in expression specification 

Antwort

0

Ich glaube nicht, Ihre Unterabfrage erlaubt ist ...

Ein kurzer Blick hier:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SubQueries

Zustände:

As of Hive 0.13 some types of subqueries are supported in the WHERE clause. Those are queries where the result of the query can be treated as a constant for IN and NOT IN statements (called uncorrelated subqueries because the subquery does not reference columns from the parent query):

+0

Oh ... gibt es einen praktischen Weg dahin? – marc

0

Sie können das collect_max UDF von Brickhouse (http://github.com/klout/brickhouse) Um dieses Problem zu lösen, in einem Wert von 1 vorbei, was bedeutet, dass Sie nur die einzelnen Max-Wert werden soll.

select array_index(map_keys(collect_max(carrier_id, meandelay, 1)), 0) from flightinfo; 

Außerdem habe ich irgendwo gelesen, dass die Hive max UDF ermöglicht es Ihnen, andere Felder auf der Zeile zuzugreifen, aber ich denke, es ist einfacher, nur collect_max zu verwenden.

2

Verwenden Sie stattdessen verbinden.

SELECT a.* FROM flightinfo a left semi join 
(SELECT CAST(MAX(meandelay) AS FLOAT) 
maxdelay FROM flightinfo)b on (a.meandelay=b.maxdelay) 
+0

Was macht der Befehl 'left semi join' hier genau? – vashts85

8

Verwenden Sie die windowing and analytics functions

SELECT carrier_id, meandelay, meancanceled 
FROM 
(SELECT carrier_id, meandelay, meancanceled, 
     rank() over (order by cast(meandelay as float) desc) as r 
    FROM table) S 
WHERE S.r = 1; 

Dies wird auch das Problem lösen, wenn mehr als eine Zeile den gleichen Maximalwert hat, werden Sie alle Zeilen als Ergebnis erhalten. Wenn Sie nur eine einzelne Zeile ändern möchten, geben Sie rank() in row_number() ein oder fügen Sie einen weiteren Begriff zur order by hinzu.