order by with analytic function

Hi gurus

Need your help again.

I have the following data.

Examples of data

Select * from

(

As with a reference

(

Select ' 100 ', ' 25' grp lb, to_date('2012-03-31') ter_dt, 'ABC' package_name FROM DUAL union all

Select ' 100 ', ' 19', to_date ('2012-03-31'), 'AA' OF the whole union DOUBLE

Select ' 200 ', ' 25', to_date('2012-03-31'), 'CC' FROM DUAL union all

Select ' 300 ', ' 28', to_date('2012-03-31'), 'XX' from DUAL union all

Select ' 300 ', ' 28', to_date('4444-12-31'), 'XY' from DUAL

)

Select the grp, lb, ter_dt, Package_name

ROW_NUMBER() over (partition by order of grp by case when lb = '19' then 1)

When lb = '25' then 2

ro_nbr end)

Reference)

-where ro_nbr = 1

;

-----------

The query above returns the following result:

Existing query result

GRP LB TER_DT package_name RO_NBR

1001903/12/31AA1
1002503/12/31ABC2
2002503/12/31CC1
3002803/12/31XX1
3002844 12-31XY2

If you can see the data above then I use the order clause with function row_number analytic and prioritize data according to LB using the order by clause.

Now the problem is I need simple stored against each group so I write the following query:

Query

Select * from

(

As with a reference

(

Select ' 100 ', ' 25' grp lb, to_date('2012-03-31') ter_dt, 'ABC' package_name FROM DUAL union all

Select ' 100 ', ' 19', to_date ('2012-03-31'), 'AA' OF the whole union DOUBLE

Select ' 200 ', ' 25', to_date('2012-03-31'), 'CC' FROM DUAL union all

Select ' 300 ', ' 28', to_date('2012-03-31'), 'XX' from DUAL union all

Select ' 300 ', ' 28', to_date('4444-12-31'), 'XY' from DUAL

)

Select the grp, lb, ter_dt, Package_name

ROW_NUMBER() over (partition by order of grp by case when lb = '19' then 1)

When lb = '25' then 2

ro_nbr end)

Reference)

where ro_nbr = 1

;

The query result

GRP LB TER_DT RO_NBR

1001903/12/31AA1
2002503/12/31CC1
3002803/12/31XX1

My required result is that 300 GRP contains 2 folders and I need the record with the latest means of ter_dt and right now, I only get the latest.

My output required

GRP LB TER_DT RO_NBR

1001903/12/31AA1
2002503/12/31CC1
3002844 12-31XY1

Please guide. Thank you

Hello

The query you posted is the ro_nbr assignment based on nothing other than lb.  When there are 2 or more lines that have an equal claim to get assigned ro_nbr = 1, then one of them is chosen arbitrarily.  If, when a tie like that occurs, you want the number 1 to be assigned based on some sort, and add another expression of Analytics ORDER BY clause, like this:

WITH got_ro_nbr AS

(

SELECT the grp, lb, ter_dt, nom_package

ROW_NUMBER () OVER (PARTITION BY grp

ORDER OF CASES

WHEN lb = '19' THEN 1

WHEN lb = '25' THEN 2

END

, ter_dt DESC-* NEW *.

) AS ro_nbr

REFERENCE

)

SELECT the grp, lb, ter_dt, nom_package

OF got_ro_nbr

WHERE ro_nbr = 1

;

Tags: Database

Similar Questions

  • get a single result with analytical functions

    SELECT delrazjn. TYPE, delrazjn. DATE, delrazjn. USER, delrazjn. The IID OF the ZKET_DR delraz, ZKET_DR_JN delrazjn
    WHERE delraz. IID = delrazjn. IID
    AND (delrazjn. TYPE = 'UP2' GOLD delrazjn. TYPE = 'An increase in 1') AND delrazjn. IID_N IS NOT NULL

    This is an example of my sql. But there is more than one result of delrazjn. IID. How can I get the first enterd in DB and ignore others, there will only be one result and no more.
    The first result came in, that I can see for delrazjn. DATE.

    I try to do that with analytical functions, but without success.

    You're right, I told you that I can't test the code.

    I hope this works now:

    SELECT delrazjn.TYPE, delrazjn.DATE, delrazjn.USER, delrazjn.IID
    FROM ZKET_DR delraz, ZKET_DR_JN delrazjn
    WHERE delraz.IID = delrazjn.IID
    AND (delrazjn.TYPE = 'UP2' OR delrazjn.TYPE = 'UP1') AND delrazjn.IID_N IS NOT NULL
    and delrazjn.date=(select min(d.date) from ZKET_DR_JN d where d.type=delrazjn.type and d.user=delrazjn.user)
    
  • Is there a shorter way (better) with analytical functions?

    Here's a little test scenario:
    create table t 
    ( id   number,
      pos  number,
      typ  number,
      m    number);
      
    insert into t values (1,1,1,100);
    insert into t values (1,2,1,100);
    insert into t values (1,3,2, 50);
    insert into t values (2,1,3, 30);
    insert into t values (2,2,4, 70);
    insert into t values (3,1,1,100);
    insert into t values (3,2,2, 50);
    insert into t values (4,1,3, 30);
    insert into t values (4,2,5, 80);
    insert into t values (4,3,3, 30);
    insert into t values (5,1,3, 30);
    insert into t values (5,2,6, 30);
    insert into t values (6,1,2, 50);
    insert into t values (6,2,7, 50);
    insert into t values (6,3,2, 50);
    insert into t values (7,1,4, 70);
    insert into t values (7,2,4, 70);
    insert into t values (7,3,4, 70);
    For each id, I want to add all the values of m only when they have a different type. It would be a long journey:
    with t1 as
      (select 
         id, 
         typ, 
         min(m) m1 
       from t
       group by id, typ)
    select
      id,
      sum(m1) f
    from t1
    group by id
    order by 1;
    
            ID          F
    ---------- ----------
             1        150 
             2        100 
             3        150 
             4        110 
             5         60 
             6        100 
             7         70 
    but I wonder, is it possible to get this result with a single statement select using analytic functions, something like
    select 
      id, 
      sum(m) over (partition by distinct typ) F    -- this does not work. It's only an idea how it might look like
    from t
    group by id;

    This is firstly a collection with the id, type with calculation of the min for each id, type the combination.
    By subsequently for each id of the sum of the minutes (for each combination of id, type for this particular id) is summarized.

    select distinct
     id, sum(min(m)) over (partition by id)
    from data
    group by id, typ
    order by id
    

    Published by: chris227 on 15.03.2013 07:39

  • Problem with analytical function for date

    Hi all

    ORCL worm:
    Oracle Database 11 g Enterprise Edition Release 11.2.0.2.0 - 64 bit Production
    PL/SQL Release 11.2.0.2.0 - Production
    "CORE 11.2.0.2.0 Production."
    AMT for Linux: Version 11.2.0.2.0 - Production
    NLSRTL Version 11.2.0.2.0 - Production

    I have a problem with the analtical for the date function. I'm trying to group records based on timestamp, but I'm failing to do.
    Could you please help me find where I'm missing.
    This is the subquery. No issue with this. I'm just posting it for reference. 
    select sum(disclosed_cost_allocation.to_be_paid_amt) amt,
        substr(reference_data.ref_code,4,10) cd,
        to_char(external_order_status.status_updated_tmstp, 'DD-MON-YYYY HH24:MI:SS') tmstp,
        DISCLOSED_CLOSING_COST.DISCLOSED_CLOSING_COST_ID id
      FROM Deal.Fee_Mapping_Definition ,
        Deal.Fee_Index_Definition ,
        Deal.Fee_Closing_Cost_Item,
        Deal.Closing_Cost,
        Deal.Document_Generation_Request,
        deal.PRODUCT_REQUEST,
        deal.External_Order_Request,
        deal.External_Order_Status,
        deal. DISCLOSED_CLOSING_COST,
        deal.DISCLOSED_COST_ALLOCATION,
        deal.reference_data
      WHERE Fee_Mapping_Definition.Fee_Code                    = Fee_Index_Definition.Fee_Code
      AND Fee_Index_Definition.Fee_Index_Definition_Id         = Fee_Closing_Cost_Item.Fee_Index_Definition_Id
      AND Fee_Closing_Cost_Item.Closing_Cost_Id                = Closing_Cost.Closing_Cost_Id
      AND CLOSING_COST.PRODUCT_REQUEST_ID                      = Document_Generation_Request.Product_Request_Id
      AND closing_cost.product_request_id                      = product_request.product_request_id
      AND Product_Request.Deal_Id                              = External_Order_Request.Deal_Id
      AND external_order_request.external_order_request_id     = external_order_status.external_order_request_id
      AND external_order_request.external_order_request_id     = disclosed_closing_cost.external_order_request_id
      AND DISCLOSED_CLOSING_COST. DISCLOSED_CLOSING_COST_ID    = DISCLOSED_COST_ALLOCATION.DISCLOSED_CLOSING_COST_ID
      AND Fee_Index_Definition.Fee_Index_Definition_Id         = Disclosed_Closing_Cost.Fee_Index_Definition_Id
      AND Fee_Mapping_Definition.Document_Line_Series_Ref_Id   = Reference_Data.Reference_Data_Id
      AND Document_Generation_Request.Document_Package_Ref_Id IN (7392 ,2209 )
      AND External_Order_Status.Order_Status_Txt               = ('GenerationCompleted')
      AND Fee_Mapping_Definition.Document_Line_Series_Ref_Id  IN ( 7789, 7788,7596 )
      AND FEE_MAPPING_DEFINITION.DOCUMENT_TYPE_REF_ID          = 1099
      AND Document_Generation_Request.Product_Request_Id      IN
        (SELECT PRODUCT_REQUEST.PRODUCT_REQUEST_id
        FROM Deal.Disclosed_Cost_Allocation,
          Deal.Disclosed_Closing_Cost,
          DEAL.External_Order_Request,
          DEAL.PRODUCT_REQUEST,
          Deal.Scenario
        WHERE Disclosed_Cost_Allocation.Disclosed_Closing_Cost_Id = Disclosed_Closing_Cost.Disclosed_Closing_Cost_Id
        AND Disclosed_Closing_Cost.External_Order_Request_Id      = External_Order_Request.External_Order_Request_Id
        AND External_Order_Request.Deal_Id                        = Product_Request.Deal_Id
        AND product_request.scenario_id                           = scenario.scenario_id
        AND SCENARIO.SCENARIO_STATUS_TYPE_REF_ID                  = 7206
        AND product_request.servicing_loan_acct_num              IS NOT NULL
        AND product_request.servicing_loan_acct_num               = 0017498379
          --AND Disclosed_Cost_Allocation.Disclosed_Cost_Allocation_Id = 5095263
        )
      GROUP BY DISCLOSED_CLOSING_COST.DISCLOSED_CLOSING_COST_ID,
        External_Order_Status.Status_Updated_Tmstp,
        Reference_Data.Ref_Code,
        disclosed_cost_allocation.to_be_paid_amt
      order by 3 desc,
        1 DESC;
    
    Result:
    2000     1304-1399     28-JUL-2012 19:49:47     6880959
    312     1302     28-JUL-2012 19:49:47     6880958
    76     1303     28-JUL-2012 19:49:47     6880957
    2000     1304-1399     28-JUL-2012 18:02:16     6880539
    312     1302     28-JUL-2012 18:02:16     6880538
    76     1303     28-JUL-2012 18:02:16     6880537
    
    
    But, when I try to group the timestamp using analytical function,
    
    
    select amt 
            ,cd 
            ,rank() over(partition by tmstp order by tmstp desc) rn 
    from 
    (select sum(disclosed_cost_allocation.to_be_paid_amt) amt,
        substr(reference_data.ref_code,4,10) cd,
        to_char(external_order_status.status_updated_tmstp, 'DD-MON-YYYY HH24:MI:SS') tmstp,
        DISCLOSED_CLOSING_COST.DISCLOSED_CLOSING_COST_ID id
      FROM Deal.Fee_Mapping_Definition ,
        Deal.Fee_Index_Definition ,
        Deal.Fee_Closing_Cost_Item,
        Deal.Closing_Cost,
        Deal.Document_Generation_Request,
        deal.PRODUCT_REQUEST,
        deal.External_Order_Request,
        deal.External_Order_Status,
        deal. DISCLOSED_CLOSING_COST,
        deal.DISCLOSED_COST_ALLOCATION,
        deal.reference_data
      WHERE Fee_Mapping_Definition.Fee_Code                    = Fee_Index_Definition.Fee_Code
      AND Fee_Index_Definition.Fee_Index_Definition_Id         = Fee_Closing_Cost_Item.Fee_Index_Definition_Id
      AND Fee_Closing_Cost_Item.Closing_Cost_Id                = Closing_Cost.Closing_Cost_Id
      AND CLOSING_COST.PRODUCT_REQUEST_ID                      = Document_Generation_Request.Product_Request_Id
      AND closing_cost.product_request_id                      = product_request.product_request_id
      AND Product_Request.Deal_Id                              = External_Order_Request.Deal_Id
      AND external_order_request.external_order_request_id     = external_order_status.external_order_request_id
      AND external_order_request.external_order_request_id     = disclosed_closing_cost.external_order_request_id
      AND DISCLOSED_CLOSING_COST. DISCLOSED_CLOSING_COST_ID    = DISCLOSED_COST_ALLOCATION.DISCLOSED_CLOSING_COST_ID
      AND Fee_Index_Definition.Fee_Index_Definition_Id         = Disclosed_Closing_Cost.Fee_Index_Definition_Id
      AND Fee_Mapping_Definition.Document_Line_Series_Ref_Id   = Reference_Data.Reference_Data_Id
      AND Document_Generation_Request.Document_Package_Ref_Id IN (7392 ,2209 )
      AND External_Order_Status.Order_Status_Txt               = ('GenerationCompleted')
      AND Fee_Mapping_Definition.Document_Line_Series_Ref_Id  IN ( 7789, 7788,7596 )
      AND FEE_MAPPING_DEFINITION.DOCUMENT_TYPE_REF_ID          = 1099
      AND Document_Generation_Request.Product_Request_Id      IN
        (SELECT PRODUCT_REQUEST.PRODUCT_REQUEST_id
        FROM Deal.Disclosed_Cost_Allocation,
          Deal.Disclosed_Closing_Cost,
          DEAL.External_Order_Request,
          DEAL.PRODUCT_REQUEST,
          Deal.Scenario
        WHERE Disclosed_Cost_Allocation.Disclosed_Closing_Cost_Id = Disclosed_Closing_Cost.Disclosed_Closing_Cost_Id
        AND Disclosed_Closing_Cost.External_Order_Request_Id      = External_Order_Request.External_Order_Request_Id
        AND External_Order_Request.Deal_Id                        = Product_Request.Deal_Id
        AND product_request.scenario_id                           = scenario.scenario_id
        AND SCENARIO.SCENARIO_STATUS_TYPE_REF_ID                  = 7206
        AND product_request.servicing_loan_acct_num              IS NOT NULL
        AND product_request.servicing_loan_acct_num               = 0017498379
          --AND Disclosed_Cost_Allocation.Disclosed_Cost_Allocation_Id = 5095263
        )
      GROUP BY DISCLOSED_CLOSING_COST.DISCLOSED_CLOSING_COST_ID,
        External_Order_Status.Status_Updated_Tmstp,
        Reference_Data.Ref_Code,
        disclosed_cost_allocation.to_be_paid_amt
      order by 3 desc,
        1 DESC);
    
    Result:
    312     1302            1
    2000     1304-1399     1
    76     1303            1
    312     1302            1
    2000     1304-1399     1
    76     1303            1 
    
    
    Required output:
    312     1302            1
    2000     1304-1399     1
    76     1303            1
    312     1302            2
    2000     1304-1399     2
    76     1303            2
    THX
    Rod.

    Hey, Rod,

    My guess is that you want:

    , dense_rank () over (order by  tmstp  desc)  AS rn 
    

    RANK means you'll jump numbers when there is a link. For example, if all 3 rows have the exact same last tmstp, all 3 rows would be assigned number 1, GRADE would assign 4 to the next line, but DENSE_RANK attributes 2.

    "PARTITION x" means that you are looking for a separate series of numbers (starting with 1) for each value of x. If you want just a series of numbers for the entire result set, then do not use a PARTITION BY clause at all. (PARTITION BY is never required.)
    Maybe you want to PARTITIONNER IN cd. I can't do it without some examples of data, as well as an explanation of why you want the results of these data.
    You certainly don't want to PARTITION you BY the same expression ORDER BY; It simply means that all the lines are tied for #1.

    I hope that answers your question.
    If not, post a small example data (CREATE TABLE and only relevant columns, INSERT statements) for all of the tables involved and also publish outcomes from these data.
    Explain, using specific examples, how you get these results from these data.
    Simplify the problem as much as possible.
    Always tell what version of Oracle you are using.
    See the FAQ forum {message identifier: = 9360002}

    Published by: Frank Kulash, August 1, 2012 13:20

  • More help with analytical functions

    I had great hellp here yesterday and I need once more today. I guess I'm still not able to get a solid understanding of analytical functions. So here's the problem:
    table with 3 collars:
    product_id (int), sale_date (to date), count_sold (int) - each file show that the number of items have been sold for the product at a given date.
    The query should return the 3 passes of the table AND a fourth column that contains the date with the best sales of the product. If there are two or more dates with equal sales, the last being is chosen.

    Is this possible using an analytical function appropriately and without using a subquery?

    example:
    product_id, sale_date, count_sold, high_sales_date
    1, 01-01-2008, 10, 05/10/2008,.
    1, 2008-03-10, 20, 10/05/2008
    1, 10/04/2008, 25, 05/10/2008
    1, 10/05/2008, 25, 05/10/2008
    1, 01/06/2008, 22, 05/10/2008
    2, 05/12/2008, 12, 05/12/2008
    2, 06/01/2009, 10, 05/12/2008

    Thank you

    Hello

    Try this:

    SELECT     product_id
    ,     sale_date
    ,     count_sold
    ,     FIRST_VALUE (sale_date) OVER ( PARTITION BY  product_id
                                   ORDER BY          count_sold          DESC
                               ,               sale_date          DESC
                             )      AS high_sales_date
    FROM     table_x;
    

    If you would post INSERT statements for your data, then I could test it.

    Focus issue: Why use FIRST_VALUE with descending order and not LAST_VALUE (ASCending) ORDER of default?

  • Help with analytical functions

    Hi all

    I'm on Oracle 11g DB and have records in the table that look like this
    transaction_ref   line_type   description
    --------------------   --------------  ---------------
     10                   DETAIL      abc123          
     10                   DETAIL      abc978          
     10                   DETAIL      test              
     10                   DETAIL      test              
     10                   DETAIL      test              
     20                   DETAIL      abcy             
     20                   DETAIL      abc9782       
     20                   DETAIL      test12          
     20                   DETAIL      test32          
    Analytical, I generate rownumber by Ref single transaction as follows:
    SELECT row_number() over (partition by transaction_ref order by 1) rownumber
    FROM mytable ;
    
    
    transaction_ref   line_type   description   rownumber
    --------------------   --------------  ---------------   ----------------
     10                   DETAIL      abc123          1
     10                   DETAIL      abc978          2
     10                   DETAIL      test              3
     10                   DETAIL      test              4
     10                   DETAIL      test              5
     20                   DETAIL      abcy             1
     20                   DETAIL      abc9782       2
     20                   DETAIL      test12          3
     20                   DETAIL      test32          4
    However, for my needs, I need my rownumber as follows:

    with the exception of number 1 of Clotilde, I want to increment the number of lines per 3
     transaction_ref   line_type   description   rownumber
    --------------------   --------------  ---------------   ----------------
     10                   DETAIL      abc123          1
     10                   DETAIL      abc978          4
     10                   DETAIL      test              7
     10                   DETAIL      test              10
     10                   DETAIL      test              13
     20                   DETAIL      abcy             1
     20                   DETAIL      abc9782       4
     20                   DETAIL      test12          7
     20                   DETAIL      test32          10
    .... 
    Thank you
    Maëlle

    Published by: user565538 on June 4, 2011 17:32

    Published by: user565538 on June 4, 2011 17:34

    Published by: user565538 on June 4, 2011 17:35
    with mytable as (
                     select 10 transaction_ref,'DETAIL' line_type,'abc123' description from dual union all
                     select 10,'DETAIL','abc978' from dual union all
                     select 10,'DETAIL','test' from dual union all
                     select 10,'DETAIL','test' from dual union all
                     select 10,'DETAIL','test' from dual union all
                     select 20,'DETAIL','abcy' from dual union all
                     select 20,'DETAIL','abc9782' from dual union all
                     select 20,'DETAIL','test12' from dual union all
                     select 20,'DETAIL','test32' from dual
                    )
    SELECT  transaction_ref,
            line_type,
            description,
            (row_number() over (partition by transaction_ref order by 1) - 1) * 3 + 1 rownumber
    FROM mytable
    /
    
    TRANSACTION_REF LINE_T DESCRIP  ROWNUMBER
    --------------- ------ ------- ----------
                 10 DETAIL abc123           1
                 10 DETAIL abc978           4
                 10 DETAIL test             7
                 10 DETAIL test            10
                 10 DETAIL test            13
                 20 DETAIL abcy             1
                 20 DETAIL abc9782          4
                 20 DETAIL test12           7
                 20 DETAIL test32          10
    
    9 rows selected.
    
    SQL> 
    

    SY.

  • Help with analytical functions - Windowing

    Hello

    I'm using Oracle 11.2.0.4.0.

    I want to do the sum of all amounts for each window of 3 days from the date of the oldest rolling.  I also want to name each window with the date limit for the period of 3 days.

    My requirement is slightly more complicated, but I use this example to illustrate what I'm trying to

    create table test (dt date, amt, run_id number);

    Insert test values (to_date (' 22/04/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 23/04/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 24/04/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 25/04/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 27/04/2015 ',' dd/mm/yyyy'), 5, 1);

    Insert test values (to_date (' 28/04/2015 ',' dd/mm/yyyy'), 2, 1);

    Insert test values (to_date (' 29/04/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 04/30/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 01/05/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 02/05/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 03/05/2015 ',' dd/mm/yyyy'), 1, 1);

    Insert test values (to_date (' 04/05/2015 ',' dd/mm/yyyy'), 1, 1);

    The output should look like the example below.  The period column requires

    to show the end of each 3-day study:

    AMT DT SUM_PER_PERIOD PERIOD

    22/04/2015 1 1 24/04/2015

    23/04/2015 1 2 24/04/2015

    24/04/2015 1 3 24/04/2015

    25/04/2015 1 3 27/04/2015

    27/04/2015 5 6 27/04/2015

    28/04/2015 2 7 30/04/2015

    29/04/2015 20 27 30/04/2015

    30/04/2015 30 52 30/04/2015

    05/01/2015 5 55 3/05/2015

    05/02/2015 5 50 3/05/2015

    05/02/2015 10 50 3/05/2015

    05/03/2015 1 21/3/05/2015

    All I can manage this is

    Select dt

    TN

    , sum (amt) on sum_per_period (PARTITION BY run_id ORDER BY dt vary from 2 PAST current line)

    of the test

    order by dt;

    Can anyone help?

    It's very kind of you to give the insert and create instructions... but I corrected the data a bit

    It does not match the output see you below

    starting from 29/04, you forgot to change the dates and numbers of...

    insert into test values (to_date('22/04/2015','dd/mm/yyyy'),1,1);
    insert into test values (to_date('23/04/2015','dd/mm/yyyy'),1,1);
    insert into test values (to_date('24/04/2015','dd/mm/yyyy'),1,1);
    insert into test values (to_date('25/04/2015','dd/mm/yyyy'),1,1);
    insert into test values (to_date('27/04/2015','dd/mm/yyyy'),5,1);
    insert into test values (to_date('28/04/2015','dd/mm/yyyy'),2,1);
    insert into test values (to_date('29/04/2015','dd/mm/yyyy'),20,1);
    insert into test values (to_date('30/04/2015','dd/mm/yyyy'),30,1);
    insert into test values (to_date('01/05/2015','dd/mm/yyyy'),5,1);
    insert into test values (to_date('02/05/2015','dd/mm/yyyy'),5,1);
    insert into test values (to_date('02/05/2015','dd/mm/yyyy'),10,1);
    insert into test values (to_date('03/05/2015','dd/mm/yyyy'),1,1);
    

    your periods will change if you insert a new first date...

    so I guess you want a specific date... in this case 22/04/2015 and a specific end date

    creation of periods from this first date and then grouping of these periods is easier with a first fixed date and a delta of 3 days.

    the first step is to match the periods to your data (adapted)

    with periods as (
      select date_start + (level-1) * period_days period_start, date_start + level * period_days period_end, period_days from (
        select to_date('21/04/2015', 'dd/mm/yyyy') date_start, to_date('04/05/2015', 'dd/mm/yyyy') date_end, 3 period_days   from dual)
      connect by date_start + level * period_days  < date_end)
    select *
    from test t, periods p
    where t.dt > p.period_start and t.dt <= p.period_end
    

    This gives your data with the dates of beginning and ending period

    DT AMT RUN_ID PERIOD_START PERIOD_END PERIOD_DAYS
    22/04/2015

    1

    1

    21/04/2015 24/04/2015

    3

    23/04/2015

    1

    1

    21/04/2015 24/04/2015

    3

    24/04/2015

    1

    1

    21/04/2015 24/04/2015

    3

    25/04/2015

    1

    1

    24/04/2015 27/04/2015

    3

    27/04/2015

    5

    1

    24/04/2015 27/04/2015

    3

    28/04/2015

    2

    1

    27/04/2015 30/04/2015

    3

    29/04/2015

    20

    1

    27/04/2015 30/04/2015

    3

    30/04/2015

    30

    1

    27/04/2015 30/04/2015

    3

    05/01/2015

    5

    1

    30/04/2015 05/03/2015

    3

    05/02/2015

    5

    1

    30/04/2015 05/03/2015

    3

    05/02/2015

    10

    1

    30/04/2015 05/03/2015

    3

    05/03/2015

    1

    1

    30/04/2015 05/03/2015

    3

    and then sum the amt during the 3 days

    with periods as (
      select date_start + (level-1) * period_days period_start, date_start + level * period_days period_end, period_days from (
        select to_date('21/04/2015', 'dd/mm/yyyy') date_start, to_date('04/05/2015', 'dd/mm/yyyy') date_end, 3 period_days   from dual)
      connect by date_start + level * period_days  < date_end)
    select t.dt, t.amt, sum(amt) over (order by t.dt range between 2 preceding and current row) sum_per_period, p.period_end period
    from test t, periods p
    where t.dt > p.period_start and t.dt <= p.period_end
    

    giving your output as requested:

    DT AMT SUM_PER_PERIOD PERIOD
    22/04/2015

    1

    1

    24/04/2015
    23/04/2015

    1

    2

    24/04/2015
    24/04/2015

    1

    3

    24/04/2015
    25/04/2015

    1

    3

    27/04/2015
    27/04/2015

    5

    6

    27/04/2015
    28/04/2015

    2

    7

    30/04/2015
    29/04/2015

    20

    27

    30/04/2015
    30/04/2015

    30

    52

    30/04/2015
    05/01/2015

    5

    55

    05/03/2015
    05/02/2015

    5

    50

    05/03/2015
    05/02/2015

    10

    50

    05/03/2015
    05/03/2015

    1

    21

    05/03/2015
  • Need help with analytical function (LAG)

    The requirement is as I have a table with described colums

    col1 County flag Flag2

    ABC 1 Y Y

    XYZ 1 Y Y

    XYZ 1 O NULL

    xyz *2* N N

    XYZ 2 Y NULL

    DEF 1 Y Y

    DEF 1 N NULL

    To get the columns Flag2

    1 assign falg2 as indicator for rownum = 1
    2 check the colm1, count of current line with colm1, Earl of the previous line. The colm1 and the NTC are identical, should assign null...


    Here's the query I used to get the values of Flag2


    SELECT colm1, count, flag
    BOX WHEN
    LAG(Count, 1,null) OVER (PARTITION BY colm1 ORDER BY colm1 DESC NULLS LAST) IS NULL
    and LAG(flag, 1, NULL) PLUS (SCORE FROM colm1 ORDER BY colm1, cycle DESC NULLS LAST) IS NULL
    THEN the flag
    END AS Flag2
    FROM table1


    but the query above returns the o/p below which is false

    col1_ County flag Flag2

    ABC 1 Y Y
    XYZ 1 Y Y
    XYZ 1 O NULL
    xyz *2* N NULL
    XYZ 2 Y NULL
    DEF 1 Y Y
    DEF 1 N NULL


    Thank you

    Published by: user9370033 on April 8, 2010 23:25

    Well, you have not enough explained your full requirement in this

    1 assign falg2 as indicator for rownum = 1
    2 check the colm1, count of current line with colm1, Earl of the previous line. The colm1 and the NTC are identical, should assign null...

    as you say not what Flag2 must be set on if com1 and cnt are not the same as the previous row.

    But how about this as my first guess what you mean...

    SQL> with t as (select 'abc' as col1, 1 as cnt, 'Y' as flag from dual union all
      2             select 'xyz', 1, 'Y' from dual union all
      3             select 'xyz', 1, 'Y' from dual union all
      4             select 'xyz', 2, 'N' from dual union all
      5             select 'xyz', 2, 'Y' from dual union all
      6             select 'def', 1, 'Y' from dual union all
      7             select 'def', 1, 'N' from dual)
      8  -- END OF TEST DATA
      9  select col1, cnt, flag
     10        ,case when lag(col1) over (order by col1, cnt) is null then flag
     11              when lag(col1) over (order by col1, cnt) = col1 and
     12                   lag(cnt) over (order by col1, cnt) = cnt then null
     13              else flag
     14         end as flag2
     15  from t
     16  /
    
    COL        CNT F F
    --- ---------- - -
    abc          1 Y Y
    def          1 Y Y
    def          1 N
    xyz          1 Y Y
    xyz          1 Y
    xyz          2 Y Y
    xyz          2 N
    
    7 rows selected.
    
    SQL>
    
  • Help with analytic function

    version 9.2

    Here is a sample
    WITH temp AS
         (SELECT 10 ID, TRUNC (SYSDATE - 1) dt, 101 ord_id
            FROM DUAL
          UNION
          SELECT 11 ID, TRUNC (SYSDATE - 1) dt, 101 ord_id
            FROM DUAL
          UNION
          SELECT 11 ID, TRUNC (SYSDATE) dt, 103 ord_id
            FROM DUAL
          UNION
          SELECT 13 ID, TRUNC (SYSDATE) dt, 104 ord_id
            FROM DUAL)
    SELECT *
      FROM temp
    Output: number of separate orders for each date
    Dt     Count
    1/25  1
    1/26  2
    ME_XE?WITH temp AS  2       (SELECT 10 ID, TRUNC (SYSDATE - 1) dt, 101 ord_id  3          FROM DUAL  4        UNION  5        SELECT 11 ID, TRUNC (SYSDATE - 1) dt, 101 ord_id  6          FROM DUAL  7        UNION  8        SELECT 11 ID, TRUNC (SYSDATE) dt, 103 ord_id  9          FROM DUAL 10        UNION 11        SELECT 13 ID, TRUNC (SYSDATE) dt, 104 ord_id 12          FROM DUAL) 13  SELECT dt, count(distinct ord_id) 14  FROM temp 15  group by dt;
    
    DT                         COUNT(DISTINCTORD_ID)-------------------------- ---------------------25-JAN-2009 12 00:00                           126-JAN-2009 12 00:00                           2
    
    2 rows selected.
    
    Elapsed: 00:00:00.01ME_XE?ME_XE?
    
  • Performance with Analytic functions

    Hello

    The following query takes more than 3 hours to run (10.2.0.4)
    any help to optimize this?

    Thanks for your help
    SELECT   DISTINCT
             MAX (NVL (A.DB_SOURCE, 'SIGNIFY')) OVER (PARTITION BY C.COUNTRY)
                DB_SOURCE,
             A.SUBJECTNUMBERSTR,
             A.SUBJECTID,
             MAX (A.SITECOUNTRY) OVER (PARTITION BY C.COUNTRY) SITECOUNTRY,
             C.COUNTRY,
             C.CENTRE,
             C.COUNTRY || '-' || C.CENTRE AS SITEMNEMONIC,
             A.VISITMNEMONIC,
             A.VISITID,
             A.FROZENSTATE,
             A.SIGNEDSTATE,
             A.INCLUS,
             A.VISDATRECTHEO,
             A.VISIT,
             A.VISIT_THEO,
             B.DOV,
             MAX (C.STUDY_INCL) OVER () STUDY_INCL,
             MAX (C.COUNTRY_INCL) OVER (PARTITION BY C.COUNTRY) COUNTRY_INCL,
             MAX (C.CENTRE_INCL) OVER (PARTITION BY C.COUNTRY, C.CENTRE)
                CENTRE_INCL,
             MAX (NVL (C.NB_VISIT_ATTENDUES_GLOBAL, 0)) OVER ()
                NB_VISIT_ATTENDUES_GLOBAL,
             MAX (NVL (C.NB_VISIT_ATTENDUES_COUNTRY, 0))
                OVER (PARTITION BY C.COUNTRY)
                NB_VISIT_ATTENDUES_COUNTRY,
             MAX (NVL (C.NB_VISIT_ATTENDUES_CENTRE, 0))
                OVER (PARTITION BY C.COUNTRY, C.CENTRE)
                NB_VISIT_ATTENDUES_CENTRE,
             MAX (D.NB_VISIT_CLEAN_GLOBAL) OVER () NB_VISIT_CLEAN_GLOBAL,
             MAX (D.NB_VISIT_CLEAN_COUNTRY) OVER (PARTITION BY C.COUNTRY)
                NB_VISIT_CLEAN_COUNTRY,
             MAX (D.NB_VISIT_CLEAN_COUNTRY)
                OVER (PARTITION BY C.COUNTRY, C.CENTRE)
                NB_VISIT_CLEAN_CENTRE,
             MAX (D.NB_VISIT_CLEAN_INCLUS_GLOBAL) OVER ()
                NB_VISIT_CLEAN_INCLUS_GLOBAL,
             MAX (D.NB_VISIT_CLEAN_INCLUS_COUNTRY) OVER (PARTITION BY C.COUNTRY)
                NB_VISIT_CLEAN_INCLUS_COUNTRY,
             MAX (D.NB_VISIT_CLEAN_INCLUS_COUNTRY)
                OVER (PARTITION BY C.COUNTRY, C.CENTRE)
                NB_VISIT_CLEAN_INCLUS_CENTRE
      FROM   CL316257083_ECRF_DW.T_BILANS_MENSUELS_TMP A,
             CL316257083_ECRF_DW.T_PASTA_UNION B,
             CL316257083_ECRF_DW.T_BILAN_SETHI C,
             CL316257083_ECRF_DW.T_BILAN_QUERIES D
     WHERE   (    A.DB_SOURCE = B.DB_SOURCE(+)
              AND A.SUBJECTID = B.SUBJECTID(+)
              AND A.VISITID = B.VISITID(+))
             AND (C.COUNTRY = A.COUNTRY(+) AND C.CENTRE = A.CENTRE(+))
             AND (D.COUNTRY(+) = A.COUNTRY AND D.CENTRE(+) = A.CENTRE);
    
    
    Plan hash value: 3745247003
    
    --------------------------------------------------------------------------------------------------------
    | Id  | Operation              | Name                  | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT       |                       | 10025 |  1556K|       |  1544  (13)| 00:00:02 |
    |   1 |  HASH UNIQUE           |                       | 10025 |  1556K|  3496K|  1544  (13)| 00:00:02 |
    |   2 |   WINDOW SORT          |                       | 10025 |  1556K|  3496K|  1544  (13)| 00:00:02 |
    |*  3 |    HASH JOIN OUTER     |                       | 10025 |  1556K|       |   915  (20)| 00:00:01 |
    |*  4 |     HASH JOIN OUTER    |                       |  5543 |   703K|       |   720  (20)| 00:00:01 |
    |*  5 |      HASH JOIN OUTER   |                       |  5543 |   552K|       |   359  (21)| 00:00:01 |
    |   6 |       TABLE ACCESS FULL| T_BILAN_SETHI         |  1277 | 43418 |       |     4   (0)| 00:00:01 |
    |   7 |       TABLE ACCESS FULL| T_BILANS_MENSUELS_TMP |   259K|    16M|       |   342  (18)| 00:00:01 |
    |   8 |      TABLE ACCESS FULL | T_PASTA_UNION         |   105K|  2884K|       |   355  (19)| 00:00:01 |
    |   9 |     TABLE ACCESS FULL  | T_BILAN_QUERIES       |   107K|  3057K|       |   189  (16)| 00:00:01 |
    --------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - access("D"."COUNTRY"(+)="A"."COUNTRY" AND "D"."CENTRE"(+)="A"."CENTRE")
       4 - access("A"."DB_SOURCE"="B"."DB_SOURCE"(+) AND "A"."SUBJECTID"="B"."SUBJECTID"(+) AND
                  "A"."VISITID"="B"."VISITID"(+))
       5 - access("C"."COUNTRY"="A"."COUNTRY"(+) AND "C"."CENTRE"="A"."CENTRE"(+))
    
    24 rows selected.
    
    Elapsed: 00:00:11.15
    with tab as
    (
    SELECT --+ materialize
             DISTINCT
             A.SUBJECTNUMBERSTR,
             A.SUBJECTID,
             C.COUNTRY,
             C.CENTRE,
             C.COUNTRY || '-' || C.CENTRE AS SITEMNEMONIC,
             A.VISITMNEMONIC,
             A.VISITID,
             A.FROZENSTATE,
             A.SIGNEDSTATE,
             A.INCLUS,
             A.VISDATRECTHEO,
             A.VISIT,
             A.VISIT_THEO,
             B.DOV
           FROM   CL316257083_ECRF_DW.T_BILANS_MENSUELS_TMP_MDE A,
             CL316257083_ECRF_DW.T_PASTA_UNION B,
             CL316257083_ECRF_DW.T_BILAN_SETHI C,
             CL316257083_ECRF_DW.T_BILAN_QUERIES D
     WHERE   (    A.DB_SOURCE = B.DB_SOURCE(+)
              AND A.SUBJECTID = B.SUBJECTID(+)
              AND A.VISITID = B.VISITID(+))
             AND (C.COUNTRY = A.COUNTRY(+) AND C.CENTRE = A.CENTRE(+))
             AND (D.COUNTRY(+) = A.COUNTRY AND D.CENTRE(+) = A.CENTRE)
    )
    SELECT   -- DISTINCT
             MAX (NVL (A.DB_SOURCE, 'SIGNIFY')) OVER (PARTITION BY C.COUNTRY)
                DB_SOURCE,
             A.SUBJECTNUMBERSTR,
             A.SUBJECTID,
             MAX (A.SITECOUNTRY) OVER (PARTITION BY C.COUNTRY) SITECOUNTRY,
             C.COUNTRY,
             C.CENTRE,
             C.COUNTRY || '-' || C.CENTRE AS SITEMNEMONIC,
             A.VISITMNEMONIC,
             A.VISITID,
             A.FROZENSTATE,
             A.SIGNEDSTATE,
             A.INCLUS,
             A.VISDATRECTHEO,
             A.VISIT,
             A.VISIT_THEO,
             B.DOV,
             MAX (C.STUDY_INCL) OVER () STUDY_INCL,
             MAX (C.COUNTRY_INCL) OVER (PARTITION BY C.COUNTRY) COUNTRY_INCL,
             MAX (C.CENTRE_INCL) OVER (PARTITION BY C.COUNTRY, C.CENTRE)
                CENTRE_INCL,
             MAX (NVL (C.NB_VISIT_ATTENDUES_GLOBAL, 0)) OVER ()
                NB_VISIT_ATTENDUES_GLOBAL,
             MAX (NVL (C.NB_VISIT_ATTENDUES_COUNTRY, 0))
                OVER (PARTITION BY C.COUNTRY)
                NB_VISIT_ATTENDUES_COUNTRY,
             MAX (NVL (C.NB_VISIT_ATTENDUES_CENTRE, 0))
                OVER (PARTITION BY C.COUNTRY, C.CENTRE)
                NB_VISIT_ATTENDUES_CENTRE,
             MAX (D.NB_VISIT_CLEAN_GLOBAL) OVER () NB_VISIT_CLEAN_GLOBAL,
             MAX (D.NB_VISIT_CLEAN_COUNTRY) OVER (PARTITION BY C.COUNTRY)
                NB_VISIT_CLEAN_COUNTRY,
             MAX (D.NB_VISIT_CLEAN_COUNTRY)
                OVER (PARTITION BY C.COUNTRY, C.CENTRE)
                NB_VISIT_CLEAN_CENTRE,
             MAX (D.NB_VISIT_CLEAN_INCLUS_GLOBAL) OVER ()
                NB_VISIT_CLEAN_INCLUS_GLOBAL,
             MAX (D.NB_VISIT_CLEAN_INCLUS_COUNTRY) OVER (PARTITION BY C.COUNTRY)
                NB_VISIT_CLEAN_INCLUS_COUNTRY,
             MAX (D.NB_VISIT_CLEAN_INCLUS_COUNTRY)
                OVER (PARTITION BY C.COUNTRY, C.CENTRE)
                NB_VISIT_CLEAN_INCLUS_CENTRE
      FROM tab;
    -- group by ???
    
  • How to use Group by in the analytic function

    I need to write the Department that has the minimum wage in a row. She must be with analytical function, but I have problem in group by. I can't use min() without group by.

    Select * from (min (sal) select min_salary, deptno, RANK() ON RN (ORDER BY sal CSA, CSA rownum) of the Group of emp by deptno) < 20 WHERE RN order by deptno;

    Published by: senza on 6.11.2009 16:09

    Hello

    senza wrote:
    I need to write the Department that has the minimum wage in a row. She must be with analytic function

    Therefore with an analytic function? Looks like it is a duty.

    The best way to get these results is with an aggregate, not analysis, function:

    SELECT      MIN (deptno) KEEP (DENSE_RANK FIRST ORDER BY sal)     AS dept_with_lowest_sal
    FROM      scott.emp
    ;
    

    Note that you do not need a subquery.
    This can be modififed if, for example, you want the lowest Department with the sal for each job.

    But if your mission is to use an analytical function, that's what you have to do.

    but I have problem in group by. I can't use min() without group by.

    Of course, you can use MIN without GROUP BY. Almost all of the aggregate (including MIN) functions have analytical equivalents.
    However, in this issue, you don't need to. The best analytical approach RANK only, not use MIN. If you ORDER BY sal, the lines with rank = 1 will have the minimum wage.

    Select * from (min (sal) select min_salary, deptno, RANK() ON RN (ORDER BY sal CSA, CSA rownum) of the Group of emp by deptno) WHERE the RN< 20="" order="" by="">

    Try to select plain old sal instead of MIN (sal) and get reid of the GROUP BY clause.

    Add ROWNUM in the ORDER BY clause is to make RANK return the same result as ROW_NUMBER, every time that it is a tie for the sal, the output will still be distinct numbers. which line gets the lower number will be quite arbitrary, and not necessarily the same every time you run the query. For example, MARTIN and WARD have exactly the same salary, 1250. The query you posted would assign rn = 4 to one of them and rn = 5 to another. Who gets 4? It's a toss-up. It could be MARTIN the first time you try, and WARD the next. (In fact, in a very small table like scott.emp, it probably will be consistent, but always arbitrary.) If this is what you want, it would be clearer and simpler just to use ROW_NUMEBR instead of RANK.

  • Order of evaluation of analytic function

    Hello

    have question quite like this:

    with

    -This query selects a 'representative' acct_id by Group (about 300 lines in total)

    acct_repres as

    (

    Select distinct acct_id, origin_id, acct_parm_id of

    (

    Select a.*

    source_id

    , dense_rank() over (partition by order source_id by nulls first, acct_id acct_nbr origin_id) as odr

    account a join account_parm on (a.parm_id = ap.acct_parm_id) ap

    )

    where odr = 1

    )

    Select col1

    col2

    , (select accct_id from ar acct_repres where ar.acct_parm_id = t2.acct_parm_id) col3

    , col4 (select count (1) of acct_repres)

    of une_table t1

    Join other_table t2 on (...)

    And here it is. "Acct_repres" subquery returns more than 300 lines when it is run separately. But when it is used in CTE sometimes (depending on the execution plan) she seems to have that one line - the value in the column col4 is '1 ',.

    While the value of col3 is NULL for most of the cases.

    It looks like the the dense_rank function and the State 'where odr = 1' are evaluated at the end.

    When I use the hint to MATERIALIZE the result was the same.

    But when I put the result of account_repres in the dedicated table and use this table instead of CTE output is correct.

    What is a bug? Or I do something wrong?

    PS: my version of db is 11 GR 1 material (11.1.0.7).

    some unorganized comments:

    -analytical functions are evaluated towards the end of the execution ("' the last set of operations performed in a query with the exception of the final ORDER BY clause"- http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions004.htm")

    -but still the result of a SQL query must be deterministic, so I think that your results are not an expected behavior

    -the CBO has some problems with common table expressions (http://jonathanlewis.wordpress.com/2012/05/24/subquery-factoring-7/) if they are of great assistance in the structuring of complex queries. In these cases, you can avoid problems by using inline views

    -Your query uses the common table expressions in scalar subqueries and scalar subqueries are also likely to confuse the CBO. In addition, they are executed once for each row in your result set (or at least for each different correlation value) and can have a negative impact on the performance of the queries in many cases. Often, they can be replaced by outer joins.

    -you say that the suspicion of materialization brings you an erroneous result: the indicator object (online) gives you the correct results?

    Concerning

    Martin Preiss

  • Purpose of the ORDER BY clause in the analytic function Min Max

    I was always using analytical functions like Min Max without ORDER BY clause. But today I used with the ORDER BY clause. The results are very different. I would like to know the purpose of the ORDER BY clause in Min, Max and analogues of analytical functions.

    user10566312 wrote:
    I was always using analytical functions like Min Max without ORDER BY clause. But today I used with the ORDER BY clause. The results are very different. I would like to know the purpose of the ORDER BY clause in Min, Max and analogues of analytical functions.

    It is a good point that many developers are not so aware. As far as I understand it the way it works.

    Some analytical functions do not need an order by or windowing clause (SUM, COUNT, MIN, etc.). If there is no specified window, then the full score is the window.
    As soon as you add a command also add you a windowing clause. This window has the default value of 'rank ofrows between unbounded preceding and current_row. So as soon as you add an order by clause, you get a sliding window.

    Documentation: http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions001.htm

    windowing_clause
    ...
    You cannot specify this clause unless you specified the order_by_clause. Window limits defined by the clause RANGE you can not specify only a single expression to the > order_by_clause. Please refer to 'Restrictions on the ORDER BY Clause'.

    example of

    with testdata as (select 10 numval, level lv from dual connect by level < 10)
    select lv, numval, sum(numval) over () sum1, sum(numval) over (order by lv) sum2
    from testdata;
    
    LV NUMVAL SUM1 SUM2
    -- ------ ---- ----
     1     10   90   10
     2     10   90   20
     3     10   90   30
     4     10   90   40
     5     10   90   50
     6     10   90   60
     7     10   90   70
     8     10   90   80
     9     10   90   90 
    

    Published by: Sven w. on 25 Sep 2012 16:57 - default behavior has been corrected. Thanks to Chris

  • Need help with the analytic function

    I want to get the highest employee details and the 2nd highest employee for a particular service. But also the Department should have more than 1 employee.
    I tried the query and it gave me the correct results. But I wonder if there is another solution than to use the subquery.

    Here is the table and the query result:
    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

    Hello

    You need a subquery, but you don't need more than that.
    Here's a way to eliminate the additional subquery:

    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
    ;
    

    Analytical functions are calculated after the clause WHERE is applied. Since we need to use the results of the analytical ROW_NUMBER function in a WHERE clause, which means that we have to calculate ROW_NUMBER in a subquery and use the results in the WHERE clause of the main query. We can call the COUNT function analytical in the same auxiliary request and use the results in the same WHERE clause of the main query.

    Would what results you if there is a link for the 2nd highest salary in some Department? For example, if you add this line to your sample data:

    select 7 ,3 ,'Sunil',8000,12000,'IT' from dual  union
    

    ? You can use RANK rather than ROW_NUMBER.

  • confusion with the analytical functions

    I created an example where I am right now with the help of analytical functions. However, I need the query below to return an additional column. I need to return the result from:-' factor_day_sales * max (sdus)'. Any ideas?

    If the first column is located and must have the following results

    777777, 5791, 10, 1.5, 15, 90, 135, 7050

    the 1350 is the result, I don't know how to do. (some how to multiply factored_day_sales max (sdus) 15 470 = 7050
    create table david_sales (
    pro_id number(38),
    salesidx number (38,6),
    tim_id number(38));
    
    truncate table david_sales
    
    create table david_compensations (
    pro_id number(38),
    tim_id number(38),
    factor number(38,6));
    
    
    insert into david_sales values
    (777777, 10.00, 5795);
    insert into david_sales values
    (777777,20.00, 5795);
    insert into david_sales values
    (777777, 30.00, 5794);
    insert into david_sales values
    (777777, 40.00, 5794);
    insert into david_sales values
    (777777, 100.00, 5793);
    insert into david_sales values
    (777777, 10.00, 5793);
    insert into david_sales values
    (777777,80.00, 5791);
    insert into david_sales values
    (777777, 10.00, 5791);
    
    insert into david_compensations values
    (777777, 5795, 1.5);
    insert into david_compensations values
    (777777, 5793, 2.0);
    insert into david_compensations values
    (777777, 5792, 1.0);
    insert into david_compensations values
    (777777, 5791, 1.5);
    
    
    
        SELECT  s.pro_id sales_pro
        ,       c.pro_id comp_pro
        ,       s.tim_id sales_tim
        ,       c.tim_id comp_tim
        ,       s.salesidx day_sales
        ,       NVL(c.factor, 1) factor
        ,       s.salesidx * NVL(c.factor, 1) factored_day_sales
        ,       sum(s.salesidx                   ) over (partition by s.pro_id order by s.pro_id, s.tim_id) Sdus
        ,       sum(s.salesidx * NVL(c.factor, 1)) over (partition by s.pro_id order by s.pro_id, s.tim_id) sumMjCj 
          FROM david_sales s
          ,    david_compensations c
          WHERE s.pro_id    = c.pro_id(+)
          AND s.tim_id      = c.tim_id(+)
          AND s.tim_id     BETWEEN 5791  AND 5795
    Thanks for looking

    Is that what you want?

        SELECT  s.pro_id sales_pro
        ,       c.pro_id comp_pro
        ,       s.tim_id sales_tim
        ,       c.tim_id comp_tim
        ,       s.salesidx day_sales
        ,       NVL(c.factor, 1) factor
        ,       s.salesidx * NVL(c.factor, 1) factored_day_sales
        ,       sum(s.salesidx                   ) over (partition by s.pro_id order by s.pro_id, s.tim_id) Sdus
        ,       sum(s.salesidx * NVL(c.factor, 1)) over (partition by s.pro_id order by s.pro_id, s.tim_id) sumMjCj
        , (s.salesidx * NVL(c.factor, 1) * sum(s.salesidx                   ) over (partition by s.pro_id order by s.pro_id, s.tim_id))
          FROM david_sales s
          ,    david_compensations c
          WHERE s.pro_id    = c.pro_id(+)
          AND s.tim_id      = c.tim_id(+)
          AND s.tim_id     BETWEEN 5791  AND 5795
    
    SALES_PRO              COMP_PRO               SALES_TIM              COMP_TIM               DAY_SALES              FACTOR                 FACTORED_DAY_SALES     SDUS                   SUMMJCJ                SUMMEDMULTI
    ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ---------------------- ----------------------
    777777                 777777                 5791                   5791                   80                     1.5                    120                    90                     135                    10800
    777777                 777777                 5791                   5791                   10                     1.5                    15                     90                     135                    1350  
    

    I get the 1350

    or did you mean:

        SELECT  s.pro_id sales_pro
        ,       c.pro_id comp_pro
        ,       s.tim_id sales_tim
        ,       c.tim_id comp_tim
        ,       s.salesidx day_sales
        ,       NVL(c.factor, 1) factor
        ,       s.salesidx * NVL(c.factor, 1) factored_day_sales
        ,       sum(s.salesidx                   ) over (partition by s.pro_id order by s.pro_id, s.tim_id) Sdus
        ,       sum(s.salesidx * NVL(c.factor, 1)) over (partition by s.pro_id order by s.pro_id, s.tim_id) sumMjCj
        ,  s.salesidx * NVL(c.factor, 1) * (sum(s.salesidx * NVL(c.factor, 1)) over (partition by s.pro_id order by s.pro_id, s.tim_id)) summedMulti
          FROM david_sales s
          ,    david_compensations c
          WHERE s.pro_id    = c.pro_id(+)
          AND s.tim_id      = c.tim_id(+)
          AND s.tim_id     BETWEEN 5791  AND 5795 
    
    SALES_PRO              COMP_PRO               SALES_TIM              COMP_TIM               DAY_SALES              FACTOR                 FACTORED_DAY_SALES     SDUS                   SUMMJCJ                SUMMEDMULTI
    777777                 777777                 5795                   5795                   10                     1.5                    15                     300                    470                    7050
    

    Note, in the second block, I changed it just to use sumMjCj instead of sDus which seems to correlate with what you wanted (15 * 470 = 7050) while sdus is 15 * 300 = 4500

    Published by: tanging on December 11, 2009 06:17

Maybe you are looking for

  • Control valve, choose which module?

    Hello world! I need to create an application with Labview with HMI etc... and I also need to control 3 solenoid valves.I have the choice for the type, and I was thinking about using those: SMC VT307 with 24Vdc power consumption 5W To fight them, I've

  • HP ENVY E1P05AV: IDT Audio Driver problems in Windows 7

    For the past few weeks, I dealt with the same audio swings and speaker problems that a lot of people here have complained.  I am aware of the updated driver for those who have Windows 8 computers, but I have a Windows 7.  This computer was purchased

  • Empty file cannot be deleted or copied from my Docs

    I downloaded a book on a highly reliable site, but he must have done it it hurt, because I don't have the book, just an empty file, that I can't remove.  I get a message "cannot read the source file or disk.  When I try to save my Docs on flash disk,

  • KB2434419 has been installed successfully six times according to the update.

    Vista Home Premium; IE8. Sounds familiar...

  • Unable to display the Find tab

    I know it has been asked and answered before, but I can't find it... : if I use LabWindows / Help / CVI libraries / help topics the installation wizard appears, but it fails with the error message: cannot display the tab search (177). If I remember c