Analytical function help needed

hi i'm using oracle 10g.
CREATE TABLE test100(
  hcim    VARCHAR2(10 BYTE),
  bcim     VARCHAR2(10 BYTE),
  num    VARCHAR2(6 BYTE),
  mindate    varchar2(10 byte))
  insert into test100 values ('03217979','03236915','76120F','10/1/2006')
  insert into test100 values ('03217979','03236916','76121F','10/1/2006')
  insert into test100 values ('03217979','03236917','76122F','10/1/2006')
  insert into test100 values ('03217979','03236918','76123F',null)
  insert into test100 values ('03217979','03236919','76124F','11/1/2009')
SELECT hcim
     , bcim
     , num
     , mindate
     , Max(TO_DATE(mindate,'MM/DD/YYYY')) OVER (PARTITION BY hcim)  AS mindate1
FROM   test100
;output:
03217979     03236915     76120F     10/1/2006     11/1/2009
03217979     03236916     76121F     10/1/2006     11/1/2009
03217979     03236919     76124F     11/1/2009     11/1/2009
03217979     03236918     76123F                  11/1/2009
03217979     03236917     76122F     10/1/2006     11/1/2009how can i show null in mindate1 column since one of the date value in mindate has a null. Only if there is no nulls then i need to show max(mindate) in mindate1
Thanks in advance

Hi,
Thanks for posting the CREATE TABLE and INSERT statements; that's very helpful.
Do you mean you want mindate1 to be NULL on every row for that hcim, because at least one row in that hcim had a NULL mindate? It would help if you posted the exact results you want. (I was typing this message before your message, clarifying this point, was posted.) It would also help to have a couple of different hcims in the sample data, at least one with a NULL mindate, and another where mindate is never NULL.
I think you want something like this:
SELECT hcim
     , bcim
     , num
     , mindate
     , FIRST_VALUE ( TO_DATE (mindate, 'MM/DD/YYYY')
                    ) OVER ( PARTITION BY  hcim
                        ORDER BY         TO_DATE (mindate, 'MM/DD/YYYY')     DESC     NULLS FIRST
                 )  AS mindate1
FROM   test100
;Output:
HCIM       BCIM       NUM    MINDATE    MINDATE1
03217979   03236916   76121F 10/1/2006
03217979   03236915   76120F 10/1/2006
03217979   03236917   76122F 10/1/2006
03217979   03236919   76124F 11/1/2009
03217979   03236918   76123FStoring dates in a VARCHAR2 column is a really bad idea. Why not use a DATE column? Coding will be simpler, errors will be fewer, and execution will be faster.
Edited by: Frank Kulash on Nov 11, 2011 4:53 PM

Similar Messages

  • Does sql analytic function help to determine continuity in occurences

    We need to solve this problem in a sql statement.
    imagine a table test with two columns
    create table test (id char(1), begin number, end number);
    and these values
    insert into test('a',1, 2);
    insert into test('a',2,3);
    insert into test('a',3,4);
    insert into test('a',7,10);
    insert into test('a',10,15);
    insert into test('b',5,9);
    insert into test('b',9,21);
    insert into test('c',1,5);
    our goal is to determine continuity in number sequence between begin and end attributes for a same id and determine min and max number from these contuinity chains.
    The result may be
    a, 1, 4
    a, 7, 15
    b, 5, 21
    c, 1, 5
    We test some analytic functions like lag, lead, row_number, min, max, partition by, etc to search a way to identify row set that represent a continuity but we didn't find a way to identify (mark) them so we can use min and max functions to extract extreme values.
    Any idea is really welcome !

    Here is our implementation in a real context for example:
    insert into requesterstage(requesterstage_i, requester_i, t_requesterstage_i, datefrom, dateto )
    With ListToAdd as
    (Select distinct support.requester_i,
    support.datefrom,
    support.dateto
    from support
    where support.datefrom < to_date('01.01.2006', 'dd.mm.yyyy')
    and support.t_relief_i = t_relief_ipar.fgetflextypologyclassitem_i(t_relief_ipar.fismedicalexpenses)
    and not exists
    (select null
    from requesterstage
    where requesterstage.requester_i = support.requester_i
    and support.datefrom < nvl(requesterstage.dateto, support.datefrom + 1)
    and nvl(support.dateto, requesterstage.datefrom + 1) > requesterstage.datefrom)
    ListToAddAnalyzed_1 as
    (select requester_i,
    datefrom,
    dateto,
    decode(datefrom,lag(dateto) over (partition by requester_i order by datefrom),0,1) data_set_start
    from ListToAdd),
    ListToAddAnalyzed_2 as
    (select requester_i,
    datefrom,
    dateto,
    data_set_start,
    sum(data_set_start) over(order by requester_i, datefrom ) data_set_id
    from ListToAddAnalyzed_1)
    select requesterstage_iseq.nextval,
    requester_i,
    t_requesterstage_ipar.fgetflextypologyclassitem_i(t_requesterstage_ipar.fisbefore2006),
    datefrom,
    decode(sign(nvl(dateto, to_date('01.01.2006', 'dd.mm.yyyy')) -to_date('01.01.2006', 'dd.mm.yyyy')), 0, to_date('01.01.2006', 'dd.mm.yyyy'), -1, dateto, 1, to_date('01.01.2006', 'dd.mm.yyyy'))
    from ( select requester_i
    , min(datefrom) datefrom
    , max(dateto) dateto
    From ListToAddAnalyzed_2
    group by requester_i, data_set_id
    );

  • Timed Function Help Needed

    Hi everyone.
    I trying to work out how to run a function after 5 seconds.
    All i'm trying to do is make some text dropdown after a set time.
    Here's my code so far:
    Code:
    import fl.transitions.easing.*;
    import fl.transitions.Tween;
    var myText:TextField = new TextField();
    var myFormat:TextFormat = new TextFormat();
    var dropText:Tween;
    var dropTextTimer:Timer = new Timer(5000, 2);
    addChild(myText);
    myFormat.size = 14;
    myFormat.color = 0x0000FF;
    myFormat.font = "Helvetica";
    myText.text = "Hello World";
    myText.autoSize = TextFieldAutoSize.LEFT;
    myText.setTextFormat(myFormat);
    dropTextTimer.addEventListener(TimerEvent.TIMER_COMPLETE, dropTextFunc);
    dropText = new Tween(myText,"y",Bounce.easeOut,myText.y,200,5,true);
    function dropTextFunc(event:TimerEvent):void
         dropText;
    At the moment the text drops down as soon as it loaded.
    Any help would be great 
    Thanks

    use:
    Code:
    import fl.transitions.easing.*;
    import fl.transitions.Tween;
    var myText:TextField = new TextField();
    var myFormat:TextFormat = new TextFormat();
    var dropText:Tween;
    var dropTextTimer:Timer = new Timer(5000, 1);
    addChild(myText);
    myFormat.size = 14;
    myFormat.color = 0x0000FF;
    myFormat.font = "Helvetica";
    myText.text = "Hello World";
    myText.autoSize = TextFieldAutoSize.LEFT;
    myText.setTextFormat(myFormat);
    dropTextTimer.addEventListener(TimerEvent.TIMER, dropTextFunc);
    dropTextTimer.start();
    function dropTextFunc(event:TimerEvent):void
         dropText = new Tween(myText,"y",Bounce.easeOut,myText.y,200,5,true);

  • Moving sum using date intervals - analytic functions help

    let's say you have the following set of data:
    DATE SALES
         09/02/2012     100
         09/02/2012     50
         09/02/2012     10
         09/02/2012     1000
         09/02/2012     20
         12/02/2012     1000
         12/02/2012     1100
         14/02/2012     1000
         14/02/2012     100
         15/02/2012     112500
         15/02/2012     13500
         15/02/2012     45000
         15/02/2012     1500
         19/02/2012     1500
         20/02/2012     400
         23/02/2012     2000
         27/02/2012     4320
         27/02/2012     300000
         01/03/2012     100
         04/03/2012     17280
         06/03/2012     100
         06/03/2012     100
         06/03/2012     4320
         08/03/2012     100
         13/03/2012     1000
    for each day i need to know the sum of the sales in the present and preceding 5 days (calendar) [not five rows].
    What qurey could i use???
    Please help!

    Hi.
    Here's one way.
    WITH data AS
         SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d,     100 n FROM DUAL UNION ALL
         SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d,     50 n FROM DUAL UNION ALL
         SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d,     10 n FROM DUAL UNION ALL
         SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d,     1000 n FROM DUAL UNION ALL
         SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d,     20 n FROM DUAL UNION ALL
         SELECT TO_DATE('12/02/2012','DD/MM/YYYY') d,     1000 n FROM DUAL UNION ALL
         SELECT TO_DATE('12/02/2012','DD/MM/YYYY') d,     1100 n FROM DUAL UNION ALL
         SELECT TO_DATE('14/02/2012','DD/MM/YYYY') d,     1000 n FROM DUAL UNION ALL
         SELECT TO_DATE('14/02/2012','DD/MM/YYYY') d,     100 n FROM DUAL UNION ALL
         SELECT TO_DATE('15/02/2012','DD/MM/YYYY') d,     112500 n FROM DUAL UNION ALL
         SELECT TO_DATE('15/02/2012','DD/MM/YYYY') d,     13500 n FROM DUAL UNION ALL
         SELECT TO_DATE('15/02/2012','DD/MM/YYYY') d,     45000 n FROM DUAL UNION ALL
         SELECT TO_DATE('15/02/2012','DD/MM/YYYY') d,     1500 n FROM DUAL UNION ALL
         SELECT TO_DATE('19/02/2012','DD/MM/YYYY') d,     1500 n FROM DUAL UNION ALL
         SELECT TO_DATE('20/02/2012','DD/MM/YYYY') d,     400 n FROM DUAL UNION ALL
         SELECT TO_DATE('23/02/2012','DD/MM/YYYY') d,     2000 n FROM DUAL UNION ALL
         SELECT TO_DATE('27/02/2012','DD/MM/YYYY') d,     4320 n FROM DUAL UNION ALL
         SELECT TO_DATE('27/02/2012','DD/MM/YYYY') d,     300000 n FROM DUAL UNION ALL
         SELECT TO_DATE('01/03/2012','DD/MM/YYYY') d,     100 n FROM DUAL UNION ALL
         SELECT TO_DATE('04/03/2012','DD/MM/YYYY') d,     17280 n FROM DUAL UNION ALL
         SELECT TO_DATE('06/03/2012','DD/MM/YYYY') d,     100 n FROM DUAL UNION ALL
         SELECT TO_DATE('06/03/2012','DD/MM/YYYY') d,     100 n FROM DUAL UNION ALL
         SELECT TO_DATE('06/03/2012','DD/MM/YYYY') d,     4320 n FROM DUAL UNION ALL
         SELECT TO_DATE('08/03/2012','DD/MM/YYYY') d,     100 n FROM DUAL UNION ALL
         SELECT TO_DATE('13/03/2012','DD/MM/YYYY') d,     1000 n FROM DUAL
    days AS
         SELECT TO_DATE('2012-02-01','YYYY-MM-DD')+(LEVEL-1) d
         FROM DUAL
         CONNECT BY LEVEL <= 60
    totals_per_day AS
         SELECT dy.d,SUM(NVL(dt.n,0)) total_day
         FROM
              data dt,
              days dy
         WHERE
              dy.d = dt.d(+)
         GROUP BY dy.d
         ORDER BY 1
    SELECT
         d,
         SUM(total_day) OVER
              ORDER BY d
             RANGE BETWEEN  5 PRECEDING AND CURRENT ROW
         ) AS five_day_total
    FROM totals_per_day;
    2012-02-01 00:00:00     0
    2012-02-02 00:00:00     0
    2012-02-03 00:00:00     0
    2012-02-04 00:00:00     0
    2012-02-05 00:00:00     0
    2012-02-06 00:00:00     0
    2012-02-07 00:00:00     0
    2012-02-08 00:00:00     0
    2012-02-09 00:00:00     1180
    2012-02-10 00:00:00     1180
    2012-02-11 00:00:00     1180
    2012-02-12 00:00:00     3280
    2012-02-13 00:00:00     3280
    2012-02-14 00:00:00     4380
    2012-02-15 00:00:00     175700
    2012-02-16 00:00:00     175700
    2012-02-17 00:00:00     175700
    2012-02-18 00:00:00     173600
    2012-02-19 00:00:00     175100
    2012-02-20 00:00:00     174400
    2012-02-21 00:00:00     1900
    2012-02-22 00:00:00     1900
    2012-02-23 00:00:00     3900
    2012-02-24 00:00:00     3900
    2012-02-25 00:00:00     2400
    2012-02-26 00:00:00     2000
    2012-02-27 00:00:00     306320
    2012-02-28 00:00:00     306320
    2012-02-29 00:00:00     304320
    2012-03-01 00:00:00     304420
    2012-03-02 00:00:00     304420
    2012-03-03 00:00:00     304420
    2012-03-04 00:00:00     17380
    2012-03-05 00:00:00     17380
    2012-03-06 00:00:00     21900
    2012-03-07 00:00:00     21800
    2012-03-08 00:00:00     21900
    2012-03-09 00:00:00     21900
    2012-03-10 00:00:00     4620
    2012-03-11 00:00:00     4620
    2012-03-12 00:00:00     100
    2012-03-13 00:00:00     1100
    2012-03-14 00:00:00     1000
    2012-03-15 00:00:00     1000
    2012-03-16 00:00:00     1000
    2012-03-17 00:00:00     1000
    2012-03-18 00:00:00     1000
    2012-03-19 00:00:00     0
    2012-03-20 00:00:00     0
    2012-03-21 00:00:00     0
    2012-03-22 00:00:00     0
    2012-03-23 00:00:00     0
    2012-03-24 00:00:00     0
    2012-03-25 00:00:00     0
    2012-03-26 00:00:00     0
    2012-03-27 00:00:00     0
    2012-03-28 00:00:00     0
    2012-03-29 00:00:00     0
    2012-03-30 00:00:00     0
    2012-03-31 00:00:00     0Hope this helps.
    Regards.

  • XML function help needed

    I am inserting an xml doc into a table with a CLOB column and have a Query such as this inside a dbms_xmlgen function :-
    SELECT XMLELEMENT("provider", XMLForest(DECODE(a1.CORP_ID,''D'',13478,''RR'',14450) as"provider-id"),
    xmlagg(XMLELEMENT( "Employee", XMLForest ( a18.EMP_FIRST_NM "first-name", a18.EMP_LAST_NM "last-name" ),XMLELEMENT("enc", XMLATTRIBUTES ( 'PWE-IL' AS "measure-set"),XMLForest ( a110.PP_DESC as "enc-flag",a18.EMP_ID as "emp-id",a12.EMP_AUX_RECORD_NBR as "Employee-group-number") )))) as "provider" .
    I want to supress the duplicated PROVIDER nodes in the resulting doc. If I remove the 'AS PROVIDER' tag, it takes the xml function XMLELEMENT on the first line as the NODE.
    I am at my wits end trying to get the duplicate tag out of the way. Please help...
    VR

    I want to supress the duplicated PROVIDER nodes in the resulting docWhat duplicate nodes are you talking about?:
    SQL> select xmlelement("provider", deptno, xmlagg(xmlelement(ename, ename))) as "provider" from emp
    group by deptno
    provider                                                                              
    <provider>10<ENAME>CLARK</ENAME><ENAME>KING</ENAME><ENAME>MILLER</ENAME></provider>   
    <provider>20<ENAME>SMITH</ENAME><ENAME>FORD</ENAME><ENAME>ADAMS</ENAME><ENAME>SCOTT</EN
    AME><ENAME>JONES</ENAME></provider>                                                   
    <provider>30<ENAME>ALLEN</ENAME><ENAME>BLAKE</ENAME><ENAME>MARTIN</ENAME><ENAME>TURNER<
    /ENAME><ENAME>JAMES</ENAME><ENAME>WARD</ENAME></provider>  

  • K8N Neo FSR Bios overclocking functions help needed

    Hi all, I am a small pc builder for the family and i have found some problems with the bios of my uncles K8N neo FSR which I recommended for him. Basically it wouldn't seem to overclock with the 'Dynamic Overclocking' function on bios v1.7 but did manually by adjusting FSB incrementally (ie from 200 to 205 Mhz). When I questioned this before someone had mentioned that it could be ok to run like this. However I have since updated the bios to v1.9 and even v2.1 as they became available but now neither seem to overclock manually nor using 'Dynamic overclocking' 
    Firstly though, can someone clear up my first conception; To test if the Dynamic Overclocking function is working can I set it to a higher setting (ie.'Commander'), save and exit bios (restarting) ---> go straight back into bios ----> go straight back into Cell Menu and check 'Current frequency of cpu' has changed?
    I only ask this as if this is the case then my Dynamic Overclocking function hasn't worked with three bios' and I wont bother with anything until I RMA the board lol, as I have never been able to change the frequency of my cpu at boot/bios stage with the dynamic overclocking function.
    Can anyone help me?

    Hi Stu, yesterday I think i found out what u mean lol. I studied a 'Sticky' ? about overclocking A64s and found some interesting stuff. Apparently overclocking the HTT is dangerous, and A64s are always at least half locked. Now with this in mind Ive been wondering if there are interlocks built into my mainboard stopping me from using the 'CPU Overclock' function to overclock my pc manually from the set 200Mhz while my HTT is still set at 4x. -I say this as the HTT on my system is 800Mhz for a socket754 Sempron 3000Bx, thus overclocking this would increase my HTT above the 800Mhz threashold (I think) lol. All sounds complex but I think Ive figured it out as Im following instructions from the sticky to lower my HTT multiplier before increasing my cpu overclock. Its hard as my mainboard has Nforce3 chipset which has different ways of overclocking to every other board lol. So far I have managed to increase the overclock, but only when the HTT multiplier is lowered to 3x. I have also lowered my cpu multiplier though, and thus am trying to figure out where my 1810Mhz clock speed has changed to 1630 lol. Will try again now. I want to raise the clock speed above 1810, keeping the HTT lower than 800 and leaving the memory alone at 400DDR lol. Im hoping the memory is seperate as it seems to be on this chipset.

  • Between 31-180days  using Sysdate function -Help needed

    I am not getting any data in between 31 days and 180days in table
    Cust_lst_prch_dt :
    02/19/2009
    01/20/2009
    My query :
    select CUST_LST_PRCH_DT from order_table
    where CUST_LST_PRCH_DT>=trunc(sysdate)-31
    and CUST_LST_PRCH_DT<=trunc(sysdate)-180
    Please help me with my query
    Regards,
    clar

    Because you want it to be
    CUST_LST_PRCH_DT BETWEEN trunc(sysdate)-180 AND trunc(sysdate)-31?
    I'm guessing you mixed up your lower / upper boundary conditions in your query. However as i said, it's guessing since you've provided very little information.

  • Analytic Function help

    TABLE T1(R1_ID,R2,R3)
    insert into t1 values(63,800,'1/1/2005')
    insert into t1 values(64,841,'1/1/2005')
    insert into t1 values(64,862,'1/1/2006')
    insert into t1 values(64,879,'4/1/2007')
    insert into t1 values(64,952,'4/1/2008')
    insert into t1 values(64,980,'2/1/2009')
    insert into t1 values(64,1010,'2/1/2010')
    insert into t1 values(64,1041,'2/1/2011')
    insert into t1 values(66,841,'1/1/2005')
    insert into t1 values(66,862,'1/1/2006')
    insert into t1 values(66,879,'4/1/2007')
    insert into t1 values(66,952,'4/1/2008')
    insert into t1 values(66,980,'2/1/2009')
    insert into t1 values(66,1010,'2/1/2010')
    insert into t1 values(66,1042,'2/1/2011')
    insert into t1 values(67,841,'1/1/2005')
    insert into t1 values(67,862,'1/1/2006')
    insert into t1 values(67,879,'4/1/2007')
    insert into t1 values(67,952,'4/1/2008')
    insert into t1 values(67,980,'2/1/2009')
    insert into t1 values(67,1009,'2/1/2010')
    insert into t1 values(67,1035,'2/1/2011')
    insert into t1 values(112,3660,'1/1/2005')
    insert into t1 values(112,3806,'1/1/2006')
    insert into t1 values(112,4500,'8/1/2006')
    insert into t1 values(112,7280,'3/1/2007')
    insert into t1 values(112,8600,'2/1/2008')
    insert into t1 values(112,8818,'5/1/2008')
    insert into t1 values(112,9170,'2/1/2009')
    insert into t1 values(112,9489,'2/1/2010')
    insert into t1 values(112,9778,'2/1/2011')
    insert into t1 values(537,7000,'11/27/2005')
    insert into t1 values(537,7000,'12/1/2005')
    SELECT distinct R1_ID,MAX(R2) OVER(PARTITION BY R1_ID),MAX(R3) OVER(PARTITION BY R1_ID)
    FROM T1
    order by R1_ID
    I WANT MAX OF R2 & R3 IN ONE SQL STATEMENT. IS THAT POSSIBLE?
    ALTHOUGH I CAN WRITE A SUBQUERY WITH R3 TO GET THE RESULT.

    with temp as(
    SELECT R1_ID,R2,R3,
    row_number() over(partition by R1_ID
    order by R2 desc,R3 desc) rn
    FROM T1)
    select * from tmp where rn=1 order by R1_ID

  • I need help with Analytic Function

    Hi,
    I have this little problem that I need help with.
    My datafile has thousands of records that look like...
    Client_Id Region Countries
    [1] [1] [USA, Canada]
    [1] [2] [Australia, France, Germany]
    [1] [3] [China, India, Korea]
    [1] [4] [Brazil, Mexico]
    [8] [1] [USA, Canada]
    [9] [1] [USA, Canada]
    [9] [4] [Argentina, Brazil]
    [13] [1] [USA, Canada]
    [15] [1] [USA]
    [15] [4] [Argentina, Brazil]
    etc
    My task is is to create a report with 2 columns - Client_Id and Countries, to look something like...
    Client_Id Countries
    [1] [USA, Canada, Australia, France, Germany, China, India, Korea, Brazil, Mexico]
    [8] [USA, Canada]
    [9] [USA, Canada, Argentina, Brazil]
    [13] [USA, Canada]
    [15] [USA, Argentina, Brazil]
    etc.
    How can I achieve this using Analytic Function(s)?
    Thanks.
    BDF

    Hi,
    That's called String Aggregation , and the following site shows many ways to do it:
    http://www.oracle-base.com/articles/10g/StringAggregationTechniques.php
    Which one should you use? That depends on which version of Oracle you're using, and your exact requirements.
    For example, is order importatn? You said the results shoudl include:
    CLIENT_ID  COUNTRIES
    1        USA, Canada, Australia, France, Germany, China, India, Korea, Brazil, Mexicobut would you be equally happy with
    CLIENT_ID  COUNTRIES
    1        Australia, France, Germany, China, India, Korea, Brazil, Mexico, USA, Canadaor
    CLIENT_ID  COUNTRIES
    1        Australia, France, Germany, USA, Canada, Brazil, Mexico, China, India, Korea?
    Mwalimu wrote:
    ... How can I achieve this using Analytic Function(s)?The best solution may not involve analytic functions at all. Is that okay?
    If you'd like help, post your best attempt, a little sample data (CREATE TABLE and INSERT statements), the results you want from that data, and an explanation of how you get those results from that data.
    Always say which version of Oracle you're using.
    Edited by: Frank Kulash on Aug 29, 2011 3:05 PM

  • Help needed with analytical function

    I want to get the employee details of the highest and 2nd highest salaried employee in a particular department. But also the department should have more than 1 employee.
    I tried the query and it gave me proper results. But I'm wondering if there is some other alternative than using the subquery.
    Here is the table and the result query :
    with t as
    select 1 emp_id,3 mgr_id,'Rajesh' emp_name,3999 salary,677 bonus,'HR' dpt_nme from dual union
    select 2 ,3 ,'Gangz',4500,800,'Finance' from dual  union
    select 3 ,4 ,'Sid',8000,12000,'IT' from dual  union
    select 4 ,null,'Ram',5000,677,'HR' from dual  union
    select 5 ,4,'Shyam',6000,677,'IT' from dual union
    select 6 ,4 ,'Ravi',9000,12000,'IT' from dual  
    select * from
    (select emp_id, mgr_id, emp_name, dpt_nme, salary, row_number() over (partition by dpt_nme order by salary desc) rn from t where dpt_nme in
    (select dpt_nme from t group by dpt_nme having count(*) > 1)) where rn < 3

    Hi,
    You need a sub-query, but you don't need more than that.
    Here's one way to eliminate the extra sub-query:
    WITH     got_analytics     AS
         SELECT  emp_id,     mgr_id,     emp_name, dpt_nme, salary
         ,     ROW_NUMBER () OVER ( PARTITION BY  dpt_nme
                                   ORDER BY          salary     DESC
                           )         AS rn
         ,     COUNT (*)     OVER ( PARTITION BY  dpt_nme
                                       )         AS dpt_cnt
         FROM     t
    SELECT  emp_id,     mgr_id,     emp_name, dpt_nme, salary
    ,     rn
    FROM     got_analytics
    WHERE     rn     < 3
    AND     dpt_cnt     > 1
    ;Analytic functions are computed after the WHERE clause is applied. Since we need to use the results of the analytic ROW_NUMBER function in a WHERE clause, that means we'll have to compute ROW_NUMBER in a sub-query, and use the results in the WHERE clause of the main query. We can call the analytic COUNT function in the same sub-query, and use its results in the same WHERE clause of the main query.
    What results would you want if there's a tie for the 2nd highest salary in some department? For example, if you add this row to your sample data:
    select 7 ,3 ,'Sunil',8000,12000,'IT' from dual  union? You may want to use RANK instead of ROW_NUMBER.

  • Need some kind of Analytical Function

    Hi Oracle experts
    I need a little help from you experts. I have a PARTY table as listed below
    The existing data
    Party key     ID_INTERNAL     EID          BID
    1          11111          123
    1          11111          321
    1          22222          321          899
    1          66666          ------          888
    New records comes
    I have to assign a party key to each record based on which attribute is matching
    Now the situation is as new records comes.
    New records comes
    ID_INTERNAL     EID          BID
    22222          555
    44444          555          
    89898          ------          888
    If I match on ID_INTERNAL I may not be able to match ID_INTERNAL 44444 and 89898 and if I match EID or BID the same situation.
    Is thera any analytical function which helps me assigning a party key to all the recoords. ALl the above records should be assigned PARTY KEY 1 only.
    Please help
    Thanks
    Rajesh

    Justin
    My main goal is to assign a party key from existing set of records to the new records which are being selected/inserted. I have to write my algoritum in such a way that the new values should match their value in existing records.
    Example
    my first new record has a value of 11111 under ID_INTERNAL and in the same record it has a value of 555 under EID attribute. so based on matching algoritum for ID INTERNAL it will be assigned existing party key 1.
    Similarly second new record has a value of 87777 under ID INTERNAL and has a value of 555 under EID and this ID INTERNAL does not exists in the target table. but the value of 555 is available under EID attribute so I have to write algoritum based on EID.
    Now the delima is my target table is as follows
    Party key PARTYID PARTYNAME
    1 11111 ITSID
    1 123 EID
    1 321 EID
    Now when new records come I have to write match algortium for ID_INTERNAL to PARTYID for Partyname='ITSID'
    Once matched this record ID INTERNAL=11111 and EID =555 assigned a party key=1. So after first record the output table slooks like
    Party key PARTYID PARTYNAME
    1 11111 ITSID
    1 123 EID
    1 321 EID
    1 555 EID
    Same way for second new record where the values are ID_INTERNAL=87777 and EID=555. I have to write match algortium based on EID because the EID value of 555 already exists in target tabel with party key.
    SO after second record the target table will look like
    Party key PARTYID PARTYNAME
    1 11111 ITSID
    1 123 EID
    1 321 EID
    1 555 EID
    1 87777 ITSID
    So this is how I have to solve this match algoritum.
    Please help me if you need any information I will be glad to provide you all.
    Thanks
    Regards
    Rajesh

  • Help with analytical function

    I successfully use the following analytical function to sum all net_movement of a position (key for a position: bp_id, prtfl_num, instrmnt_id, cost_prc_crncy) from first occurrence until current row:
    SELECT SUM (net_movement) OVER (PARTITION BY bp_id, prtfl_num, instrmnt_id, cost_prc_crncy ORDER BY TRUNC (val_dt) RANGE BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING) holding,
    what i need is another column to sum net_movement of a position but only for the current date, but all my approaches fail..
    - add the date (val_dt) to the 'partition by' clause and therefore sum only values with same position and date
    SELECT SUM (net_movement) OVER (PARTITION BY val_dt, bp_id, prtfl_num, instrmnt_id, cost_prc_crncy ORDER BY TRUNC (val_dt) RANGE BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING) today_net_movement
    - take the holding for the last date and subtract it from the current holding afterwards
    SELECT SUM (net_movement) OVER (PARTITION BY bp_id, prtfl_num, instrmnt_id, cost_prc_crncy ORDER BY TRUNC (val_dt) RANGE BETWEEN UNBOUNDED PRECEDING AND -1 FOLLOWING) last_holding,
    - using lag on the analytical function which calculates holding fails too
    I also want to avoid creating a table which stores the last holding..
    Does anyone sees where I make a mistake or knows an alternative to get this value?
    It would help me much!
    Thanks in advance!

    Thank you,
    but I already tried that but it returns strange values which are not the correct ones for sure.
    It is always the same value for each row, if its not 0, and a very high one (500500 for example), even if the sum of all net_movement of that date is 0 (and the statement for holding returns 0 too)
    I also tried witch trunc(val_dt,'DDD') with the same result (without trunc it is the same issue)
    please help if you can, thanks in advance!

  • Need analytic function suggestion

    Hi,
    I need advice related to analytic ( I think ) function in Oracle 9.
    create table testx ( id number, arr number, fore number, actual number, result_x number, is_first number);
    insert into testx values ( 1, null, null, 12, null , 0 );
    insert into testx values ( 2, null, null, 14 , null, 0 );
    insert into testx values ( 3, 4, 5, 16, 16, 1 );
    insert into testx values ( 4, 5, 5, 18, 16, 0 );
    insert into testx values ( 5, 5, 5, 20, 16, 0 );
    insert into testx values ( 6, 5, 5, 22, 16, 0 );
    insert into testx values ( 7, 5, 5, 24, 16, 0 );
    insert into testx values ( 8, 5, 5, 25, 16, 0 );
    insert into testx values ( 9, 5, 8, 25, 13, 0 );
    insert into testx values ( 10, 5, 8, 21, 10, 0 );
    insert into testx values ( 11, 5, 8, 19, 7, 0 );
    insert into testx values ( 12, 5, 8, 18, 4, 0 );
    I need ONE level query ( no subqueries ) which will calculate value stored in RESULT_X column.
    Rule for calculation is:
    1. when arr and fore columns are available first time then result_x = actual ( row with id = 3)
    2. in other case result_x = (previous value of result_x + arr - fore )
    3. order of records is stored in id column
    I have problem with calculating previous value of result_x since it should be available in next row calculation and dependents on other columns values.
    Thanks for help,
    Regards,
    Piotr

    Hi, Piotr,
    This produces the results you requested:
    SELECT       testx.*
    ,       SUM ( CASE
                  WHEN  is_first = 1
                  THEN  result_x
                  ELSE  arr - fore
                 END
               ) OVER (ORDER BY  id)     AS computed_result_x
    FROM      testx
    ORDER BY  id
    ;This relies on the fact that there is only one row where is_first=1, and that all the earlier rows have NULL as arr or fore.
    If that's not the case in your real data, then I don't think it's possible in SQL without sub-queries. Why can't you use a sub-query?
    The problem is that rows up to the one with is_first=1 have to be treated differently from rows after that point, so ithe CASE expression might need to know if a given row is before or after the one with is_first=1. If you need an analytic function to determine that, then you need a sub-query, becuase analytic functions can not be nested.
    You could use MODEL or a recursive WITH clause to get the results you want, but they require sub-querries.

  • About FIRST_ROW analytic function; can anyone help?

    Hi everyone,
    Can anyone help me with this simple query?
    Let's suppose I have this query (the with clause contains some data):
    WITH T AS (
    SELECT 'TEST' as COL1, 1 as COL2, 'z' as COL3 FROM dual
    UNION ALL
    SELECT 'TEST', 2, 'y' FROM dual
    UNION ALL
    SELECT 'TEST', 2, 'h' FROM dual
    SELECT FIRST_VALUE(COL1) OVER (PARTITION BY COL1), COL2, COL3
      FROM T;I would like to have only the first row returned. I was thinking that with FIRST_VALUE it will be possible, but it returns 3 records.
    So can anyone help me to have only the first record returned?
    TEST     1     zThis is just a simple example. In reality I have thousands of records. I need to get only the first record based on the name (TEST in this example). We don't really care about the other columns.
    Thanks for your help,

    user13117585 wrote:
    I would like to have only the first row returned. I was thinking that with FIRST_VALUE it will be possible, but it returns 3 records. Analytic functions don't filter rows, they just calculate values from some part of the result set.
    Aggregating is the most efficient way of doing this query:
    SQL> WITH T AS (
      2  SELECT 'TEST' as COL1, 1 as COL2, 'z' as COL3 FROM dual
      3  UNION ALL
      4  SELECT 'TEST', 2, 'y' FROM dual
      5  UNION ALL
      6  SELECT 'TEST', 2, 'h' FROM dual
      7  )
      8  select col1
      9       , min(col2) col2
    10       , max(col3) keep (dense_rank first order by col2) col3
    11    from t
    12   group by col1
    13  /
    COL1       COL2 C
    TEST          1 z
    1 row selected.Regards,
    Rob.

  • Need valuable guidance to make a peformance oriented query, trying to replace unions with analytical function

    Hi,
       Please find below table structure and insert scritps. Requesting for vluable help.
    create table temp2 (col1 number,col2 varchar2(10),col3 number,col4 varchar2(20));
    insert into temp2 values (1,'a',100,'vvv');
    insert into temp2 values (2,'b',200,'www'); 
    insert into temp2 values (3,'c',300,'xxx');
    insert into temp2 values (4,'d',400,'yyy');   
    insert into temp2 values (5,'e',500,'zzz');
    insert into temp2 values (6,'f',600,'aaa');
    insert into temp2 values (7,'g',700,'bbb'); 
    insert into temp2 values (8,'h',800,'ccc');
    I am trying to get same output, what we get from below UNION query with ANALYTICAL Function.
    select * from temp2 where col1 in (1,2,3,4,5)
    union
    select * from temp2 where col1 in (1,2,5,6)
    union
    select * from temp2 where col1 in (1,2,7,8);
    I am seeking help by this dummy example to understand the concept, how can we use analytical functional over UNION or OUTER JOINS.
    In my exact query, I am using same table three times adding UNION clause. here also we scan temp2 three times, so for bulky tables using 'union'  would be hampering query's performance
    It means i go with three time scans of same table that is not performance oriented. With the help of above required concept, i will try to remove UNIONs from my exact query.
    Thanks!!

    Thanks for your time BluShadow and sorry as i think i couldn't make my query clear.
    I try it again. Below there are three queries, you may see all three queries are using same tables. Difference in all three queries are just few conditions, which makes all three queries diff with each other.
    I know, u cant run below query in your database, but i think it will convey my doubt to you. I have mentioned no. of rows with each clause and total i am getting 67 rows as my output. (Reason may be first n third query's result set are the subset of Second Query dataset)
    So i want to take all common rows as well as additional rows, if present in any of the query. This is getting easliy done with UNION clause but want to have it in other way as here my same is getting scanned again n again.
    SELECT
             START_TX.FX_TRAN_ID START_FX_TRAN_ID
            ,END_TX.FX_TRAN_ID END_FX_TRAN_ID
            ,START_TX.ENTERED_DT_TS
            ,USER
            ,START_TX.TRADE_DT
            ,START_TX.DEAL_NUMBER
            ,START_TX.FX_DEAL_TYPE
            ,START_TX.ORIENTATION_BUYSELL
            ,START_TX.BASE_CCY
            ,START_TX.BASE_CCY_AMT
            ,START_TX.SECONDARY_CCY
            ,START_TX.SECONDARY_CCY_AMT
            ,START_TX.MATURITY_DT
            ,START_TX.TRADE_RT
            ,START_TX.FORWARD_PTS              
            ,START_TX.CORPORATE_PIPS           
            ,START_TX.DEAL_OWNER_INITIALS      
            ,START_TX.CORPORATE_DEALER         
            ,START_TX.PROFIT_CENTER_CD
            ,START_TX.COUNTERPARTY_NM
            ,START_TX.COUNTERPARTY_NUMBER
      FROM
          (SELECT * FROM FX_TRANSACTIONS WHERE GMT_CONV_ENTERED_DT_TS >=  TO_DATE('20-Nov-2013 4:00:01 AM','DD-Mon-YYYY HH:MI:SS AM')) START_TX
           INNER JOIN
          (SELECT * FROM FX_TRANSACTIONS WHERE GMT_CONV_ENTERED_DT_TS <=  TO_DATE('20-Nov-2013 4:59:59 PM','DD-Mon-YYYY HH:MI:SS AM'))  END_TX
       ON START_TX.COUNTERPARTY_NM        = END_TX.COUNTERPARTY_NM         AND
          START_TX.COUNTERPARTY_NUMBER    = END_TX.COUNTERPARTY_NUMBER     AND
          START_TX.FX_DEAL_TYPE           = END_TX.FX_DEAL_TYPE            AND
          START_TX.BASE_CCY               = END_TX.BASE_CCY                AND
          START_TX.SECONDARY_CCY          = END_TX.SECONDARY_CCY           AND
          NVL(START_TX.CORPORATE_DEALER,'nullX')=NVL(END_TX.CORPORATE_DEALER,'nullX')       AND
          START_TX.ORIENTATION_BUYSELL='B'                                 AND 
          END_TX.ORIENTATION_BUYSELL='S'                                  AND
          START_TX.FX_TRAN_ID = 1850718                                  AND
         (START_TX.BASE_CCY_AMT           = END_TX.BASE_CCY_AMT          
          OR
          START_TX.SECONDARY_CCY_AMT      = END_TX.SECONDARY_CCY_AMT)        -- 10 Rows
    UNION
    SELECT
             START_TX.FX_TRAN_ID START_FX_TRAN_ID
            ,END_TX.FX_TRAN_ID END_FX_TRAN_ID
            ,START_TX.ENTERED_DT_TS
            ,USER
            ,START_TX.TRADE_DT
            ,START_TX.DEAL_NUMBER
            ,START_TX.FX_DEAL_TYPE
            ,START_TX.ORIENTATION_BUYSELL
            ,START_TX.BASE_CCY
            ,START_TX.BASE_CCY_AMT
            ,START_TX.SECONDARY_CCY
            ,START_TX.SECONDARY_CCY_AMT
            ,START_TX.MATURITY_DT
            ,START_TX.TRADE_RT
            ,START_TX.FORWARD_PTS              
            ,START_TX.CORPORATE_PIPS           
            ,START_TX.DEAL_OWNER_INITIALS      
            ,START_TX.CORPORATE_DEALER         
            ,START_TX.PROFIT_CENTER_CD
            ,START_TX.COUNTERPARTY_NM
            ,START_TX.COUNTERPARTY_NUMBER
      FROM
          (SELECT * FROM FX_TRANSACTIONS WHERE GMT_CONV_ENTERED_DT_TS >=  TO_DATE('20-Nov-2013 4:00:01 AM','DD-Mon-YYYY HH:MI:SS AM')) START_TX
           INNER JOIN
          (SELECT * FROM FX_TRANSACTIONS WHERE GMT_CONV_ENTERED_DT_TS <=  TO_DATE('20-Nov-2013 4:59:59 PM','DD-Mon-YYYY HH:MI:SS AM'))  END_TX
       ON START_TX.COUNTERPARTY_NM        = END_TX.COUNTERPARTY_NM         AND
          START_TX.COUNTERPARTY_NUMBER    = END_TX.COUNTERPARTY_NUMBER     AND
          START_TX.FX_DEAL_TYPE           = END_TX.FX_DEAL_TYPE            AND
          START_TX.BASE_CCY               = END_TX.BASE_CCY                AND
          START_TX.SECONDARY_CCY          = END_TX.SECONDARY_CCY           AND
          NVL(START_TX.CORPORATE_DEALER,'nullX')=NVL(END_TX.CORPORATE_DEALER,'nullX')  AND
          START_TX.FX_TRAN_ID = 1850718                                  AND
          START_TX.ORIENTATION_BUYSELL='B'                                 AND 
          END_TX.ORIENTATION_BUYSELL='S'                        --                                   67 Rows
    UNION 
    SELECT
             START_TX.FX_TRAN_ID START_FX_TRAN_ID
            ,END_TX.FX_TRAN_ID END_FX_TRAN_ID
            ,START_TX.ENTERED_DT_TS
            ,USER
            ,START_TX.TRADE_DT
            ,START_TX.DEAL_NUMBER
            ,START_TX.FX_DEAL_TYPE
            ,START_TX.ORIENTATION_BUYSELL
            ,START_TX.BASE_CCY
            ,START_TX.BASE_CCY_AMT
            ,START_TX.SECONDARY_CCY
            ,START_TX.SECONDARY_CCY_AMT
            ,START_TX.MATURITY_DT
            ,START_TX.TRADE_RT
            ,START_TX.FORWARD_PTS              
            ,START_TX.CORPORATE_PIPS           
            ,START_TX.DEAL_OWNER_INITIALS      
            ,START_TX.CORPORATE_DEALER         
            ,START_TX.PROFIT_CENTER_CD
            ,START_TX.COUNTERPARTY_NM
            ,START_TX.COUNTERPARTY_NUMBER
      FROM
          (SELECT * FROM FX_TRANSACTIONS WHERE GMT_CONV_ENTERED_DT_TS >=  TO_DATE('20-Nov-2013 4:00:01 AM','DD-Mon-YYYY HH:MI:SS AM')) START_TX
           INNER JOIN
          (SELECT * FROM FX_TRANSACTIONS WHERE GMT_CONV_ENTERED_DT_TS <=  TO_DATE('20-Nov-2013 4:59:59 PM','DD-Mon-YYYY HH:MI:SS AM'))  END_TX
       ON START_TX.COUNTERPARTY_NM        = END_TX.COUNTERPARTY_NM         AND
          START_TX.COUNTERPARTY_NUMBER    = END_TX.COUNTERPARTY_NUMBER     AND
          START_TX.FX_DEAL_TYPE           = END_TX.FX_DEAL_TYPE            AND
          START_TX.BASE_CCY               = END_TX.BASE_CCY                AND
          START_TX.SECONDARY_CCY          = END_TX.SECONDARY_CCY           AND
          NVL(START_TX.CORPORATE_DEALER,'nullX')=NVL(END_TX.CORPORATE_DEALER,'nullX') AND
          START_TX.ORIENTATION_BUYSELL='B'                                 AND 
          END_TX.ORIENTATION_BUYSELL='S'                                   AND
          START_TX.FX_TRAN_ID = 1850718                                  AND
            END_TX.BASE_CCY_AMT BETWEEN (START_TX.BASE_CCY_AMT - (START_TX.BASE_CCY_AMT * :PERC_DEV/100)) AND (START_TX.BASE_CCY_AMT + (START_TX.BASE_CCY_AMT * :PERC_DEV/100))        
            OR
            END_TX.SECONDARY_CCY_AMT BETWEEN (START_TX.SECONDARY_CCY_AMT - (START_TX.SECONDARY_CCY_AMT*:PERC_DEV/100) ) AND (START_TX.SECONDARY_CCY_AMT + (START_TX.SECONDARY_CCY_AMT*:PERC_DEV/100))
        );                                                       ---                              10 Rows

Maybe you are looking for