2017-01-29 7 views
3

Ich habe eine Tabelle mit mehreren Spalten, die sowohl Monat als auch Jahr enthält. Ich versuche anhand von column1, column2 zu identifizieren, was der größte Monat und das beste Jahr ist.Max Wert basierend auf zwei Spalten

Ich habe eine DDL für eine Testtabelle als solche.

CREATE TABLE "TEST" 
    ( "COLUMN1" VARCHAR2(6 BYTE), 
    "COLUMN2" VARCHAR2(6 BYTE), 
    "YEAR" NUMBER, 
    "MONTH" NUMBER 
    ); 

Dies sind die Daten in der Beispieltabelle.

REM INSERTING into TEST 
SET DEFINE OFF; 
Insert into TEST (COLUMN1,COLUMN2,YEAR,MONTH) values ('A','A',11,4); 
Insert into TEST (COLUMN1,COLUMN2,YEAR,MONTH) values ('A','A',14,3); 
Insert into TEST (COLUMN1,COLUMN2,YEAR,MONTH) values ('A','A',11,5); 
Insert into TEST (COLUMN1,COLUMN2,YEAR,MONTH) values ('A','A',14,1); 

Ich möchte den Rekord mit dem maximalen Monat und Jahr erhalten. Wenn ich versuche, den Datensatz abzurufen mit dieser Abfrage

SELECT t.COLUMN1, t.COLUMN2, max(t.YEAR), max(t.MONTH) 
FROM TEST t 
group by COLUMN1, COLUMN2; 

ich dies führt

enter image description here

Es scheint mir, dass es die max Jahr und max Monat unabhängig von den anderen Spalten trennt. Das erwartete Ergebnis sollte enter image description here

sein, wie kann ich nach unten auf die entsprechenden Ergebnisse zu erzielen? Ich habe mehrere Self-Joins vergeblich versucht.

+0

Darf ich fragen, warum Sie den Monat und das Jahr in getrennten Spalten speichern? –

+0

@Tim ERP-Lösung, nicht mein Design – Miguel

Antwort

3

Sie verwenden möchten Oracle-internen LAST (oder FIRST) mit MAX wie folgt aus:

SELECT t.COLUMN1, 
    t.COLUMN2, 
    MAX(t.YEAR), 
    MAX(t.MONTH) keep (dense_rank last ORDER BY YEAR nulls first) MONTH 
FROM TEST t 
GROUP BY COLUMN1, 
    COLUMN2; 

Es wird nur die max des Monats in letzten Jahr finden.

+0

Vielen Dank mein Freund, der ist brillant. – Miguel

+2

@Miguel - Oft ist das "erste" MAX (wie das MAX in diesem Beispiel in Jahr) einzigartig, und die Verwendung von MAX (...) mit der FIRST/LAST Funktion wird nicht wirklich benötigt - es nimmt die 'MAX' aus einer Menge von nur einem Wert auf. Jedoch kann Oracle dies zum Zeitpunkt der Analyse nicht wissen (ohne alle Daten zu sehen), so dass es immer noch eine Aggregatfunktion benötigt (in diesem Fall im Monat) Beispiel ist eine hervorragende Darstellung der ** vollen ** Potenz von 'FIRST/LAST', wobei' MAX' mit 'keep (dose_rank first/last order by ...)' tatsächlich voll genutzt wird. – mathguy

+0

@mathguy thanks für die Erklärung, es war auch für mich eine Augenweide. – Miguel

0

Sie können auch irgendwie beide Werte verketten, max berechnen und dann teilen. Im Falle von Jahr und Monat, können Sie Monate seit irgendeiner Epoche berechnen:

select column1, column2, 
     trunc(max(year*12+month-1)/12) year, 
     mod (max(year*12+month-1),12)+1 month 
    from test 
group by column1, column2 
Verwandte Themen