简体   繁体   中英

Adding a corresponding date to max value

The query that I have written below is giving me everything that I need except for the corresponding High_Water date. Basically what this query is doing is simple. Its giving me the MAX value throughout the life of the symbol however I'm not sure how to write in to the query so that the result set will show a 5th column with the corresponding date of the MAX value!

For example if a symbol X was entered in to the database on 01/01/2015 and it contains data up until today (11/06/2015). My current query will find the MAX AUM for symbol X and that max value was on 06/01/2015. I need my query to show me the 06/01/2015 date. Basically I need the query to find the MAX value and its corresponding date so that I know on what date the MAX AUM is reflected on.

SELECT
    A.SMBL,
    B.MLTPL,
    BEGINNING_DATE,
    ROUND(max(AUM/1000000.00)) AS HIGH_WATER_AUM      
FROM
    TBL1 A 
    JOIN TBL2 B ON A.SMBL = B.SMBL
WHERE
    A.SMBL IN = 'X' 
GROUP BY
    A.SMBL, B.MLTPL, BEGINNING_DATE
ORDER BY
    SMBL

Sounds like you need KEEP FIRST/LAST:

select   a.smbl,
         b.mltpl,
         beginning_date,
         round(max(aum / 1000000.00)) as high_water_aum,
         max(high_water_date) keep (dense_rank first order by aum desc) hw_dt_of_max_row
from     tbl1 a 
         inner join tbl2 b on (a.smbl = b.smbl)
where    a.smbl = 'X'
group by a.smbl,
         b.mltpl,
         beginning_date
order by smbl;

The keep (dense_rank first order by aum desc) bit is doing the ordering and picking the row(s) with the highest aum. (You could rewrite this as keep (dense_rank last order by aum) if you wanted to.)

The max(high_water_date) is there in case there's more than one row that has the highest aum value - it simply picks the latest high_water_date to display. You could change that to min(high_water_date) if you so wished.


Here's a simple example illustrating the principle:

with sample_data as (select 1 id, 20 val1 from dual union all
                     select 2 id, 10 val1 from dual union all
                     select 3 id, 40 val1 from dual union all
                     select 4 id, 100 val1 from dual union all
                     select 5 id, 70 val1 from dual union all
                     select 6 id, 100 val1 from dual union all
                     select 7 id, 80 val1 from dual union all
                     select 8 id, 70 val1 from dual union all
                     select 9 id, 90 val1 from dual)
select max(val1) max_val1,
       max(id) keep (dense_rank first order by val1 desc) max_val1_max_id1,
       max(id) keep (dense_rank last order by val1) max_val1_max_id2
from   sample_data;

  MAX_VAL1 MAX_VAL1_MAX_ID1 MAX_VAL1_MAX_ID2
---------- ---------------- ----------------
       100                6                6

Just create a row_number to select the highest row.

SELECT *
FROM 
    (
      SELECT A.SMBL, 
             B.MLTPL, 
             BEGINNING_DATE, 
             ROUND(AUM/1000000.00) AS HIGH_WATER_AUM,
             A.nav_date,      
             ROW_NUMBER() over 
                (PARTITION BY A.SMBL, B.MLTPL, BEGINNING_DATE ORDER BY AUM DESC) AS RN
      FROM TBL1 A 
      JOIN TBL2 B 
        ON A.SMBL = B.SMBL
      WHERE A.SMBL IN ('X','Y','Z')
    ) t
WHERE RN = 1
ORDER BY SMBL

Here is the query that I was looking to write. I gives me the exact result set that I was looking for.

SELECT A.SMBL,
       B.MLTPL,
       BEGINNING_DATE,
       ROUND(MAX(c.AUM / 1000000.00)) AS HIGH_WATER_AUM,
       max(a.nav_date) AS HIGH_WATER_AUM
FROM TBL1 A
INNER JOIN TBL2 B
        ON A.SMBL = B.SMBL
INNER JOIN (
           SELECT SMBL,
                  max(AUM) AS AUM
           FROM TBL1
           GROUP BY symbol
           ) c
        ON A.SMBL = C.SMBL
       AND c.AUM = a.AUM
WHERE A.SMBL IN ('X','Y','Z')
GROUP BY A.SMBL,
         B.MLTPL,
         BEGINNING_DATE
ORDER BY SMBL

@JuanCarlosOropeza. The result set that I was looking for is this

SMBL    MLTPL   BEGINNING_DATE       MAX(A.NAV_DATE)      HIGH_WATER_AUM
A        10    2008-12-01 00:00:00   2011-05-02 00:00:00         100
B        10    2011-10-04 00:00:00   2013-11-27 00:00:00         600
X        10    2008-11-24 00:00:00   2009-06-17 00:00:00         300
Y        10    2008-11-24 00:00:00   2015-03-26 00:00:00         500
Z        10    2008-12-01 00:00:00   2011-09-02 00:00:00         700

The result set that your query gave me was

SMBL     MLTPL  BEGINNING_DATE       MAX(A.NAV_DATE)       HIGH_WATER_AUM
A        10    2008-12-01 00:00:00   2015-10-15 00:00:00         100
B        10    2011-10-04 00:00:00   2015-10-15 00:00:00         600
X        10    2008-11-24 00:00:00   2015-10-15 00:00:00         300
Y        10    2008-11-24 00:00:00   2015-10-15 00:00:00         500
Z        10    2008-12-01 00:00:00   2015-10-15 00:00:00         700

You can see how its simply assigning a date to all of the different symbols even though their HIGHT_WATER_AUM in reality was on different dates.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM