2017-01-27 4 views
0

Können Sie mir bitte helfen, eine Abfrage für dieses Szenario zu bekommen. Im folgenden Fall sollte ich eine einzelne Zeile von A = 13 zurückgeben, da 13,14 in Spalte A die meisten Vorkommen hat und der Wert von B (30) für 13 größer ist. Wir sind an maximalen Vorkommen von A interessiert und im Falle von Unentschieden sollte B als Tiebreaker betrachtet werden.11g Oracle Aggregat SQL-Abfrage

A B 
13 30 
13 12 
14 10 
14 25 
15 5 

Im folgenden Fall, in dem einzelnen Vorkommen von A (alle gebunden) es 14 mit Maximalwert von 40 für B.

A B 
13 30 
14 40 
15 5 

Use Case zurückgeben soll - wir Anrufe von Firmenkunden zu bekommen. Wir sind daran interessiert zu wissen, zu welchen Stunden des Tages die meisten Anrufe kommen und im Falle eines Unentschiedens - welche der am stärksten frequentierten Stunden hat den längsten Anruf.

Weitere Frage

Es gibt weitere Fragen dazu. Ich möchte eine der beiden Lösungen verwenden - "11g oder niedriger" von @GurV oder "dicht_Rank" von @mathguy in größeren Abfrage unten, wie kann ich es tun.

SELECT dv.id , u.email , dv.email_subject AS headline , dv.start_date , dv.closing_date, b.name AS business_name, ls.call_cost, dv.currency, 
    SUM(lsc.duration) AS duration, COUNT(lsc.id) AS call_count, ROUND(AVG(lsc.duration), 2) AS avg_duration 
    -- max(extract(HOUR from started)) keep (dense_rank last order by count(duration), max(duration)) as most_popular_hour 
    FROM deal_voucher dv 
     JOIN lead_source ls ON dv.id = ls.deal_id 
     JOIN lead_source_call lsc ON ls.PHONE_SID = lsc.phone_number_id 
     JOIN business b ON dv.business_id = b.id 
     JOIN users u ON b.id = u.business_id 
     AND TRUNC(dv.closing_date) = to_date('13-01-2017', 'dd-mm-yyyy') 
     AND lsc.status = 'completed' and lsc.duration >= 30 
    GROUP BY dv.id , u.email , dv.email_subject , dv.start_date , dv.closing_date, b.name, ls.call_cost, dv.currency 
--, extract(HOUR from started) 
+0

wenn 14, dann wird insgesamt 35 und nicht 40! meinst du diese nach A-Spalte und Summe B-Werte zu gruppieren? – Saif

+0

@ Smart, das ist nicht erwartet, Ausgabe, das ist der zweite Fall der Eingabe – GurV

+0

@smart danke. Es hat nichts mit der Summe von B zu tun. B ist die Anrufdauer in Minuten. –

Antwort

2

dies versuchen, wenn 12c +

select a 
from t 
group by a 
order by count(*) desc, max(b) desc 
fetch first 1 row only; 

Wenn 11g oder niedriger:

select * from (
    select a 
    from t 
    group by a 
    order by count(*) desc, max(b) desc 
) where rownum = 1; 

Beachten Sie, dass, wenn es gleich Zahl und gleich Maximalwert für zwei oder mehr Werte von A, dann Jeder von ihnen wird abgeholt werden.

+0

danke @Gurv. Ich interessiere mich für max (b) als Summe (b) –

+0

@Sammy. . . Aktualisiert. – GurV

+0

Vielen Dank @Gurv. Dies ist die beste Antwort. Alles funktioniert jetzt. –

0

Hier ist eine Abfrage, die in älteren Versionen funktioniert (keine fetch Klausel) und keine Unterabfrage erfordert. Es verwendet die first/last Funktion. Im Falle von Bindungen mit "count by A" und "value of max (B)" wird nur die Zeile mit dem größten Wert von A ausgewählt. Sie können dies in min(A) oder sogar in sum(A) ändern (obwohl das wahrscheinlich nicht der Fall ist) Sinn in Ihrem Problem) oder LISTAGG(A, ',') WITHIN GROUP (ORDER BY A), um eine Komma-getrennte Liste der A zu bekommen, die für den ersten Platz gebunden sind, aber das erfordert 11.2 (glaube ich).

select max(a) keep (dense_rank last order by count(b), max(b)) as a 
     , max(max(b)) keep (dense_rank last order by count(b)) as b 
from  inputs 
group by a 
;