Using analytical function to calculate concurrency between date range

Folks,
I'm trying to use analytical functions to come up with a query that gives me the
concurrency of jobs executing between a date range.
For example:
JOB100 - started at 9AM - stopped at 11AM
JOB200 - started at 10AM - stopped at 3PM
JOB300 - started at 12PM - stopped at 2PM
The query would tell me that JOB1 ran with a concurrency of 2 because JOB1 and JOB2
were running started and finished within the same time. JOB2 ran with the concurrency
of 3 because all jobs ran within its start and stop time. The output would look like this.
JOB START STOP CONCURRENCY
=== ==== ==== =========
100 9AM 11AM 2
200 10AM 3PM 3
300 12PM 2PM 2
I've been looking at this post, and this one if very similar...
Analytic functions using window date range
Here is the sample data..
CREATE TABLE TEST_JOB
( jobid NUMBER,
created_time DATE,
start_time DATE,
stop_time DATE
insert into TEST_JOB values (100, sysdate -1, to_date('05/04/08 09:00:00','MM/DD/YY hh24:mi:ss'), to_date('05/04/08 11:00:00','MM/DD/YY hh24:mi:ss'));
insert into TEST_JOB values (200, sysdate -1, to_date('05/04/08 10:00:00','MM/DD/YY hh24:mi:ss'), to_date('05/04/08 13:00:00','MM/DD/YY hh24:mi:ss'));
insert into TEST_JOB values (300, sysdate -1, to_date('05/04/08 12:00:00','MM/DD/YY hh24:mi:ss'), to_date('05/04/08 14:00:00','MM/DD/YY hh24:mi:ss'));
select * from test_job;
JOBID|CREATED_TIME |START_TIME |STOP_TIME
----------|--------------|--------------|--------------
100|05/04/08 09:28|05/04/08 09:00|05/04/08 11:00
200|05/04/08 09:28|05/04/08 10:00|05/04/08 13:00
300|05/04/08 09:28|05/04/08 12:00|05/04/08 14:00
Any help with this query would be greatly appreciated.
thanks.
-peter

after some checking the model rule wasn't working exactly as expected.
I believe it's working right now. I'm posting a self-contained example for completeness sake.I use 2 functions to convert back and forth between epoch unix timestamps, so
I'll post them here as well.
Like I said I think this works okay, but any feedback is always appreciated.
-peter
CREATE OR REPLACE FUNCTION date_to_epoch(p_dateval IN DATE)
RETURN NUMBER
AS
BEGIN
return (p_dateval - to_date('01/01/1970','MM/DD/YYYY')) * (24 * 3600);
END;
CREATE OR REPLACE FUNCTION epoch_to_date (p_epochval IN NUMBER DEFAULT 0)
RETURN DATE
AS
BEGIN
return to_date('01/01/1970','MM/DD/YYYY') + (( p_epochval) / (24 * 3600));
END;
DROP TABLE TEST_MODEL3 purge;
CREATE TABLE TEST_MODEL3
( jobid NUMBER,
start_time NUMBER,
end_time NUMBER);
insert into TEST_MODEL3
VALUES (300,date_to_epoch(to_date('05/07/2008 10:00','MM/DD/YYYY hh24:mi')),
date_to_epoch(to_date('05/07/2008 19:00','MM/DD/YYYY hh24:mi')));
insert into TEST_MODEL3
VALUES (200,date_to_epoch(to_date('05/07/2008 09:00','MM/DD/YYYY hh24:mi')),
date_to_epoch(to_date('05/07/2008 12:00','MM/DD/YYYY hh24:mi')));
insert into TEST_MODEL3
VALUES (400,date_to_epoch(to_date('05/07/2008 10:00','MM/DD/YYYY hh24:mi')),
date_to_epoch(to_date('05/07/2008 14:00','MM/DD/YYYY hh24:mi')));
insert into TEST_MODEL3
VALUES (500,date_to_epoch(to_date('05/07/2008 11:00','MM/DD/YYYY hh24:mi')),
date_to_epoch(to_date('05/07/2008 16:00','MM/DD/YYYY hh24:mi')));
insert into TEST_MODEL3
VALUES (600,date_to_epoch(to_date('05/07/2008 15:00','MM/DD/YYYY hh24:mi')),
date_to_epoch(to_date('05/07/2008 22:00','MM/DD/YYYY hh24:mi')));
insert into TEST_MODEL3
VALUES (100,date_to_epoch(to_date('05/07/2008 09:00','MM/DD/YYYY hh24:mi')),
date_to_epoch(to_date('05/07/2008 23:00','MM/DD/YYYY hh24:mi')));
commit;
SELECT jobid,
epoch_to_date(start_time)start_time,
epoch_to_date(end_time)end_time,
n concurrency
FROM TEST_MODEL3
MODEL
DIMENSION BY (start_time,end_time)
MEASURES (jobid,0 n)
(n[any,any]=
count(*)[start_time<= cv(start_time),end_time>=cv(start_time)]+
count(*)[start_time > cv(start_time) and start_time <= cv(end_time), end_time >= cv(start_time)]
ORDER BY start_time;
The results look like this:
JOBID|START_TIME|END_TIME |CONCURRENCY
----------|---------------|--------------|-------------------
100|05/07/08 09:00|05/07/08 23:00| 6
200|05/07/08 09:00|05/07/08 12:00| 5
300|05/07/08 10:00|05/07/08 19:00| 6
400|05/07/08 10:00|05/07/08 14:00| 5
500|05/07/08 11:00|05/07/08 16:00| 6
600|05/07/08 15:00|05/07/08 22:00| 4

Similar Messages

  • Date ranges - possible to use analytic functions?

    The next datastructure needs to be converted to a daterange datastructure.
    START_DATE END_DATE      AMMOUNT
    01-01-2010 28-02-2010         10
    01-02-2010 31-03-2010         20
    01-03-2010 31-05-2010         30
    01-09-2010 31-12-2010         40Working solution:
    with date_ranges
    as   ( select to_date('01-01-2010','dd-mm-yyyy') start_date
           ,      to_date('28-02-2010','dd-mm-yyyy') end_date
           ,      10                                 ammount
           from   dual
           union all
           select to_date('01-02-2010','dd-mm-yyyy') start_date
           ,      to_date('31-03-2010','dd-mm-yyyy') end_date
           ,      20                                 ammount
           from   dual
           union all
           select to_date('01-03-2010','dd-mm-yyyy') start_date
           ,      to_date('31-05-2010','dd-mm-yyyy') end_date
           ,      30                                 ammount
           from   dual
           union all
           select to_date('01-09-2010','dd-mm-yyyy') start_date
           ,      to_date('31-12-2010','dd-mm-yyyy') end_date
           ,      40                                 ammount
           from   dual
    select   rne.start_date
    ,        lead (rne.start_date-1,1)  over (order by rne.start_date) end_date
    ,        ( select sum(dre2.ammount)
               from   date_ranges dre2
               where  rne.start_date >= dre2.start_date
               and    rne.start_date <= dre2.end_date
             ) range_ammount
    from     ( select dre.start_date
               from   date_ranges dre
               union -- implicit distinct
               select dre.end_date + 1
               from   date_ranges dre
             ) rne
    order by rne.start_date
    /Output:
    START_DATE END_DATE   RANGE_AMMOUNT
    01-01-2010 31-01-2010            10
    01-02-2010 28-02-2010            30
    01-03-2010 31-03-2010            50
    01-04-2010 31-05-2010            30
    01-06-2010 31-08-2010
    01-09-2010 31-12-2010            40
    01-01-2011
    7 rows selected.However, I would like to use an analytic function to calculate the range_ammount. Is this possible?
    Edited by: user5909557 on Jul 29, 2010 6:19 AM

    Hi,
    Welcome to the forum!
    Yes, you can replace the scalar sub-queriy with an analytic SUM, like this:
    WITH  change_data   AS
         SELECT     start_date     AS change_date
         ,     ammount          AS net_amount
         FROM     date_ranges
        UNION
         SELECT     end_date + 1     AS change_date
         ,     -ammount        AS net_amount
         FROM     date_ranges
    ,     got_range_amount     AS
         SELECT     change_date          AS start_date
         ,     LEAD (change_date) OVER (ORDER BY  change_date) - 1
                                     AS end_date
         ,     SUM (net_amount)   OVER (ORDER BY  change_date)
                                    AS range_amount
         FROM    change_data
    ,     got_grp          AS
         SELECT     start_date
         ,     end_date
         ,     range_amount
         ,     ROW_NUMBER () OVER ( ORDER BY        start_date, end_date)
               - ROW_NUMBER () OVER ( PARTITION BY  range_amount
                                         ORDER BY          start_date, end_date
                           )         AS grp
         FROM    got_range_amount
    SELECT       MIN (start_date)     AS start_date
    ,       MAX (end_date)     AS end_date
    ,       range_amount
    FROM       got_grp
    GROUP BY  grp
    ,            range_amount
    ORDER BY  grp
    ;This should be much more efficient.
    The code is longer than what you posted. That's largely because it consolidates consecutive groups with the same amount.
    For example, if we add this row to the sample data:
           union all
           select to_date('02-01-2010','dd-mm-yyyy') start_date
           ,      to_date('30-12-2010','dd-mm-yyyy') end_date
           ,      0                                 ammount
           from   dualThe query you posted produces:
    START_DAT END_DATE  RANGE_AMMOUNT
    01-JAN-10 01-JAN-10            10
    02-JAN-10 31-JAN-10            10
    01-FEB-10 28-FEB-10            30
    01-MAR-10 31-MAR-10            50
    01-APR-10 31-MAY-10            30
    01-JUN-10 31-AUG-10             0
    01-SEP-10 30-DEC-10            40
    31-DEC-10 31-DEC-10            40
    01-JAN-11I assume you only want a new row of output when the range_amount changes., that is:
    START_DAT END_DATE  RANGE_AMOUNT
    01-JAN-10 31-JAN-10           10
    01-FEB-10 28-FEB-10           30
    01-MAR-10 31-MAR-10           50
    01-APR-10 31-MAY-10           30
    01-JUN-10 31-AUG-10            0
    01-SEP-10 31-DEC-10           40
    01-JAN-11                      0Of course, you could modify the original query so that it did this, but it would end up about as complex as the query above, but less efficient.
    Conversely, if you prefer the longer output, then you don't need the suib-query got_grp in the query above.
    Thanks for posting the CREATE TABLE and INSERT statments; that's very helpful.
    There are some people who have been using this forum for years who still have to be begged to do that.

  • How to use Analytic functions in Forms10g

    Hi,
    Can we use Analytic function in forms10g like Lead & Lag.
    Thanks & Regards,

    Use a db view as a data source of your form block ....
    Greetings...
    Sim

  • [b]Using Analytic functions...[/b]

    Hi All,
    I need help in writing a query using analytic functions.
    Foll is my scenario. I have a table cust_points
    CREATE TABLE cust_points
    ( cust_id varchar2(10),
    pts_dt date,
    reward_points number(3),
    bal_points number(3)
    insert into cust_points values ('ABC',01-MAY-2004',5, 15)
    insert into cust_points values ('ABC',05-MAY-2004',3, 12)
    insert into cust_points values ('ABC',09-MAY-2004',3, 9)
    insert into cust_points values ('XYZ',02-MAY-2004',8, 4)
    insert into cust_points values ('XYZ',03-MAY-2004',5, 1)
    insert into cust_points values ('JKL',10-MAY-2004',5, 11)
    I want a result set which shows for each customer, the sum of reward his/her points
    but balance points as of the last date. So for the above I should have foll results
    cust_id reward_pts bal_points
    ABC 11 9
    XYZ 13 1
    JKL 5 11
    I having tried using last_value(), for eg
    Select cust_id, sum(reward_points), last_value(bal_points) over (partition by cust_id)...but run into grouping errors.
    Can anyone help ?

    try this...
    SELECT a.pkcol,
         nvl(SUM(b.col1),0) col1,
         nvl(SUM(b.col2),0) col2,
         nvl(SUM(b.col3),0) col3
    FROM table1 a, table2 b, table3 c
    WHERE a.pkcol = b.plcol(+)
    AND a.pkcol = c.pkcol
    GROUP BY a.pkcol;
    SQL> select a.deptno,
    2 nvl((select sum(sal) from test_emp b where a.deptno = b.deptno),0) col1,
    3 nvl((select sum(comm) from test_emp b where a.deptno = b.deptno),0) col2
    4 from test_dept a;
    DEPTNO COL1 COL2
    10 12786 0
    20 13237 738
    30 11217 2415
    40 0 0
    99 0 0
    SQL> select a.deptno,
    2 nvl(sum(b.sal),0) col1,
    3 nvl(sum(b.comm),0) col2
    4 from test_dept a,test_emp b
    5 where a.deptno = b.deptno
    6 group by a.deptno;
    DEPTNO COL1 COL2
    30 11217 2415
    20 13237 738
    10 12786 0
    SQL> select a.deptno,
    2 nvl(sum(b.sal),0) col1,
    3 nvl(sum(b.comm),0) col2
    4 from test_dept a,test_emp b
    5 where a.deptno = b.deptno(+)
    6 group by a.deptno;
    DEPTNO COL1 COL2
    10 12786 0
    20 13237 738
    30 11217 2415
    40 0 0
    99 0 0
    SQL>

  • Query for using "analytical functions" in DWH...

    Dear team,
    I would like to know if following task can be done using analytical functions...
    If it can be done using other ways, please do share the ideas...
    I have table as shown below..
    Create Table t As
    Select *
    From
    Select 12345 PRODUCT, 'W1' WEEK,  10000 SOH, 0 DEMAND, 0 SUPPLY,     0 EOH From dual Union All
    Select 12345,         'W2',       0,         100,      50,        0 From dual Union All
    Select 12345,         'W3',       0,         100,      50,        0 From dual Union All
    Select 12345,         'W4',       0,         100,      50,        0 From dual
    PRODUCT     WEEK     SOH     DEMAND     SUPPLY     EOH
    12345     W1     10,000     0     0     10000
    12345     W2     0     100     50     0
    12345     W3     0     100     50     0
    12345     W4     0     100     50     0
    Now i want to calcuate EOH (ending on hand) quantity for W1...
    This EOH for W1 becomes SOH (Starting on hand) for W2...and so on...till end of weeks
    The formula is :- EOH = SOH - (DEMAND + SUPPLY)
    The output should be as follows...
    PRODUCT     WEEK     SOH     DEMAND     SUPPLY     EOH
    12345     W1     10,000               10000
    12345     W2     10,000     100     50     9950
    12345     W3     9,950     100     50     9900
    12345     W4     9,000     100     50     8950
    Kindly share your ideas...

    Nicloei W wrote:
    Means SOH_AFTER_SUPPLY for W1, should be displayed under SOH FOR W2...i.e. SOH for W4 should be SOH_AFTER_SUPPLY for W3, right?
    If yes, why are you expecting it to be 9000 for W4??
    So in output should be...
    PRODUCT WE        SOH     DEMAND     SUPPLY        EOH SOH_AFTER_SUPPLY
    12345 W1      10000          0          0          0            10000
    12345 W2      10000      100         50          0             9950
    12345 W3      9950       100         50          0             *9900*
    12345 W4      *9000*       100         50          0             9850
    per logic you explained, shouldn't it be *9900* instead???
    you could customize Martin Preiss's logic for your requirement :
    SQL> with
      2  data
      3  As
      4  (
      5  Select 12345 PRODUCT, 'W1' WEEK,  10000 SOH, 0 DEMAND, 0 SUPPLY,   0 EOH Fom dual Union All
      6  Select 12345,         'W2',       0,         100,      50,        0 From dal Union All
      7  Select 12345,         'W3',       0,         100,      50,        0 From dal Union All
      8  Select 12345,         'W4',       0,         100,      50,        0 From dual
      9  )
    10  Select Product
    11  ,Week
    12  , Sum(Soh) Over(Partition By Product Order By Week)- Sum(Supply) Over(Parttion By Product Order By Week)+Supply Soh
    13  ,Demand
    14  ,Supply
    15  , Sum(Soh) Over(Partition By Product Order By Week)- Sum(Supply) Over(Partition By Product Order By Week) eoh
    16  from  data;
       PRODUCT WE        SOH     DEMAND     SUPPLY        EOH
         12345 W1      10000          0          0      10000
         12345 W2      10000        100         50       9950
         12345 W3       9950        100         50       9900
         12345 W4       9900        100         50       9850 Vivek L

  • Restrict Query Resultset  which uses Analytic Function

    Gents,
    Problem Definition: Using Analytic Function, get Total sales for the Product P1
    and Customer C1 [Total sales for the customer itself] in one line.
    I want to restrict the ResultSet of the query to Product P1,
    please look at the data below, queries and problems..
    Data
    Customer Product Qtr Sales
    C1 P1 19991 100.00
    C1 P1 19992 125.00
    C1 P1 19993 175.00
    C1 P1 19994 300.00
    C1 P2 19991 100.00
    C1 P2 19992 125.00
    C1 P2 19993 175.00
    C1 P2 19994 300.00
    C2 P1 19991 100.00
    C2 P1 19992 125.00
    C2 P1 19993 175.00
    C2 P1 19994 300.00
    Problem, I want to display....
    Customer Product ProdSales CustSales
    C1 P1 700 1400
    But Without using outer query, i.e. please look below for the query that
    returns this reult with two select, I want this result in one query only..
    Select * From ----*** want to avoid this... ***----
    (Select Customer,Product,
    Sum(Sales) ProdSales,
    Sum(Sum(Sales)) Over(Partition By Customer) CustSales
    From t1
    Where customer='C1')
    Where
    Product='P1' ;
    Also, I want to avoid Hard coding of P1 in the select clause....
    I mean, I can do it in one shot/select, but look at the query below, it uses
    P1 in the select clause, which is No No!! P1 is allowed only in Where or Having ..
    Select Customer,Decode(Product, 'P1','P1','P1') Product,
    Decode(Product,'P1',Sales,0) ProdSales,
    Sum(Sum(Sales)) Over (Partition By Customer ) CustSales
    From t1
    Where customer='C1' ;
    This will get me what I want, but as I said earlier, I want to avoid using P1 in the
    Select clause..
    Goal is to Avoid using
    1-> Two Select/Outer Query/In Line Views
    2-> Product 'P1' in the Select clause...
    Thanks
    -Dhaval Rasania

    I don't understand goal number 1 of not using an inline view.
    What is the harm?

  • Use Planning Function to calculate new value

    Hi All,
    I have what seems to be a simple problem, but no success in resolving.
    I have 3 planning keyfigures:
    -Units
    -Price
    -Value
    The price field is populated from another planning sheet.
    The unit field is entered by the user.
    The value should be calculated by planning function when button pushed.
    I have tried just basic "Value=Units*Price", but always comes back zero.
    I have also tried more complex "{Value, CharA, CharB, CharC} = {Units, CharA, CharB...." for each characteristic.  Still zero.
    It must be multipling by zero, but not sure how to avoid.
    If I put "Value=Price", it works. If I put "Value=Units", it works. If I put "Value=Units+Price", it works.
    Please help.
    Terrence

A: Use Planning Function to calculate new value

Here is the details.
In the infoprovider the data is like this:
Country/    Product/     Unit Sales/     Price/      Value
DE/             Shirt/            50/                 0/             0
DE/             Shirt/              0/             100.00/        0
The query is display:
Country/    Product/     Unit Sales/     Price/      Value
DE/             Shirt/            50/              100.00/         0
I have tried the following 2 formulas:
Formula 1:
= {Unit Sales} *
Formula 2:
FOREACH Country, Product.
{Value, Country, Product} = {Unit Sales, Country, Product} * {Price, Country, Product}
ENDFOR.
Both return zero for values.
Thanks,
Terrence

Here is the details.
In the infoprovider the data is like this:
Country/    Product/     Unit Sales/     Price/      Value
DE/             Shirt/            50/                 0/             0
DE/             Shirt/              0/             100.00/        0
The query is display:
Country/    Product/     Unit Sales/     Price/      Value
DE/             Shirt/            50/              100.00/         0
I have tried the following 2 formulas:
Formula 1:
= {Unit Sales} *
Formula 2:
FOREACH Country, Product.
{Value, Country, Product} = {Unit Sales, Country, Product} * {Price, Country, Product}
ENDFOR.
Both return zero for values.
Thanks,
Terrence

  • Using analytic function to get the right output.

    Dear all;
    I have the following sample date below
    create table temp_one
           id number(30),  
          placeid varchar2(400),
          issuedate  date,
          person varchar2(400),
          failures number(30),
          primary key(id)
    insert into temp_one values (1, 'NY', to_date('03/04/2011', 'MM/DD/YYYY'), 'John', 3);
    insert into temp_one values (2, 'NY', to_date('03/03/2011', 'MM/DD/YYYY'), 'Adam', 7);
    insert into temp_one values (3, 'Mexico', to_date('03/04/2011', 'MM/DD/YYYY'), 'Wendy', 3);
    insert into temp_one values (4, 'Mexico', to_date('03/14/2011', 'MM/DD/YYYY'), 'Gerry', 3);
    insert into temp_one values (5, 'Mexico', to_date('03/15/2011', 'MM/DD/YYYY'), 'Zick', 9);
    insert into temp_one values (6, 'London', to_date('03/16/2011', 'MM/DD/YYYY'), 'Mike', 8);this is output I desire
    placeid       issueperiod                               failures
    NY              02/28/2011 - 03/06/2011          10
    Mexico       02/28/2011 - 03/06/2011           3
    Mexico        03/14/2011 - 03/20/2011          12
    London        03/14/2011 - 03/20/2011          8All help is appreciated. I will post my query as soon as I am able to think of a good logic for this...

    hI,
    user13328581 wrote:
    ... Kindly note, I am still learning how to use analytic functions.That doesn't matter; analytic functions won't help in this problem. The aggregate SUM function is all you need.
    But what do you need to GROUP BY? What is each row of the result set going to represent? A placeid? Yes, each row will represent only one placedid, but it's going to be divided further. You want a separate row of output for every placeid and week, so you'll want to GROUP BY placeid and week. You don't want to GROUP BY the raw issuedate; that would put March 3 and March 4 into separate groups. And you don't want to GROUP BY failures; that would mean a row with 3 failures could never be in the same group as a row with 9 failures.
    This gets the output you posted from the sample data you posted:
    SELECT       placeid
    ,             TO_CHAR ( TRUNC (issuedate, 'IW')
                  , 'MM/DD/YYYY'
                ) || ' - '|| TO_CHAR ( TRUNC (issuedate, 'IW') + 6
                                             , 'MM/DD/YYY'
                               )     AS issueperiod
    ,       SUM (failures)                  AS sumfailures
    FROM        temp_one
    GROUP BY  placeid
    ,            TRUNC (issuedate, 'IW')
    ;You could use a sub-query to compute TRUNC (issuedate, 'IW') once. The code would be about as complicated, efficiency probably won't improve noticeably, and the the results would be the same.

  • Using analytical function - value with highest count

    Hi
    i have this table below
    CREATE TABLE table1
    ( cust_name VARCHAR2 (10)
    , txn_id NUMBER
    , txn_date DATE
    , country VARCHAR2 (10)
    , flag number
    , CONSTRAINT key1 UNIQUE (cust_name, txn_id)
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9870,TO_DATE ('15-Jan-2011', 'DD-Mon-YYYY'), 'Iran', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9871,TO_DATE ('16-Jan-2011', 'DD-Mon-YYYY'), 'China', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9872,TO_DATE ('17-Jan-2011', 'DD-Mon-YYYY'), 'China', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9873,TO_DATE ('18-Jan-2011', 'DD-Mon-YYYY'), 'Japan', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9874,TO_DATE ('19-Jan-2011', 'DD-Mon-YYYY'), 'Japan', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9875,TO_DATE ('20-Jan-2011', 'DD-Mon-YYYY'), 'Russia', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9877,TO_DATE ('22-Jan-2011', 'DD-Mon-YYYY'), 'China', 0);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9878,TO_DATE ('26-Jan-2011', 'DD-Mon-YYYY'), 'Korea', 0);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9811,TO_DATE ('17-Jan-2011', 'DD-Mon-YYYY'), 'China', 0);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9854,TO_DATE ('13-Jan-2011', 'DD-Mon-YYYY'), 'Taiwan', 0);
    The requirement is to create an additional column in the resultset with country name where the customer has done the maximum number of transactions
    (with transaction flag 1). In case we have two or more countries tied with the same count, then we need to select the country (among the tied ones)
    where the customer has done the last transaction (with transaction flag 1)
    e.g. The count is 2 for both 'China' and 'Japan' for transaction flag 1 ,and the latest transaction is for 'Japan'. So the new column should contain 'Japan'
    CUST_NAME TXN_ID TXN_DATE COUNTRY FLAG country_1
    Peter 9811 17-JAN-11 China 0 Japan
    Peter 9854 13-JAN-11 Taiwan 0 Japan
    Peter 9870 15-JAN-11 Iran 1 Japan
    Peter 9871 16-JAN-11 China 1 Japan
    Peter 9872 17-JAN-11 China 1 Japan
    Peter 9873 18-JAN-11 Japan 1 Japan
    Peter 9874 19-JAN-11 Japan 1 Japan
    Peter 9875 20-JAN-11 Russia 1 Japan
    Peter 9877 22-JAN-11 China 0 Japan
    Peter 9878 26-JAN-11 Korea 0 Japan
    Please let me know how to accomplish this using analytical functions
    Thanks
    -Learnsequel

    Does this work (not spent much time checking it)?
    WITH ana AS (
    SELECT cust_name, txn_id, txn_date, country, flag,
            Sum (flag)
                OVER (PARTITION BY cust_name, country)      n_trx,
            Max (CASE WHEN flag = 1 THEN txn_date END)
                OVER (PARTITION BY cust_name, country)      l_trx
      FROM cnt_trx
    SELECT cust_name, txn_id, txn_date, country, flag,
            First_Value (country) OVER (PARTITION BY cust_name ORDER BY n_trx DESC, l_trx DESC) top_cnt
      FROM ana
    CUST_NAME      TXN_ID TXN_DATE  COUNTRY          FLAG TOP_CNT
    Fred             9875 20-JAN-11 Russia              1 Russia
    Fred             9874 19-JAN-11 Japan               1 Russia
    Peter            9873 18-JAN-11 Japan               1 Japan
    Peter            9874 19-JAN-11 Japan               1 Japan
    Peter            9872 17-JAN-11 China               1 Japan
    Peter            9871 16-JAN-11 China               1 Japan
    Peter            9811 17-JAN-11 China               0 Japan
    Peter            9877 22-JAN-11 China               0 Japan
    Peter            9875 20-JAN-11 Russia              1 Japan
    Peter            9870 15-JAN-11 Iran                1 Japan
    Peter            9878 26-JAN-11 Korea               0 Japan
    Peter            9854 13-JAN-11 Taiwan              0 Japan
    12 rows selected.

  • Help on Using Analytical Functions

    I am hetting error when i use Analytical functions in Expressions
    AVG( INGRP1.Test1 ) OVER (PARTITION BY INGRP1.Test2)
    Error is as follows
    Line 1, Col 28:
    PLS-00103: Encountered the symbol "OVER" when expecting one of the following:
    * & = - + ; < / > at in is mod remainder not rem
    <an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_
    LIKE4_ LIKEC_ between || multiset member SUBMULTISET_

    Hi,
    the syntax of this part of the sql statement is okay. Please post the complete statement to identify the error.
    Sometimes oracle identifies the wrong point for the error.
    Regards,
    Detlef

  • Is it possible using Analytical functions?

    Hi,
       I have the following data
        Column1      Column2
        2005            500
        2006            500
        2007            500
        2008            500
    Now, if I've some variable value as 800, then the output record should be
        Column1         Column2
        2008               500
        2007               300
        2006                  0
        2005                  0i.e. the Column2 value(order by column1 desc) is split to accommodate the variable passed.
    Right now, it's being done in PL/SQL. Is it possible to do it in SQL using Analytical function?
    Thanks,
    Sundar
    P.S: It doesnt have to be using analytical, if it can be achieved in a SQL, it's good.
    Message was edited by:
    Sundar M

    Hi, a sample using analytical function SUM:
    CREATE TABLE Source_Data
               ( Year NUMBER
               , Value NUMBER
    BEGIN
       DELETE FROM Source_Data;
       FOR v_Cycle IN 1 .. 6
       LOOP
          INSERT
            INTO Source_Data
                 Year
               , Value
          VALUES
                 2000 + v_Cycle
               , 100 * v_Cycle
       END LOOP;
       COMMIT;
    END;
    VARIABLE v_Amount NUMBER
    EXECUTE :v_Amount := 1200using the SUM, the previous values are totalized:
    so
    SELECT Year
         , Value Year_Value
         , :v_Amount Original_Amount
         , SUM(Value) OVER (ORDER BY Year DESC RANGE UNBOUNDED PRECEDING) Cumulative_Sum
         , DECODE(
                   SIGN(:v_Amount - SUM(Value) OVER (ORDER BY Year DESC RANGE UNBOUNDED PRECEDING))
                   , 1, Value              -- Positive number, more value can be subtract
                   , GREATEST(Value - (SUM(Value) OVER (ORDER BY Year DESC RANGE UNBOUNDED PRECEDING) - :v_Amount), 0)
                 )         Year_Quota
      FROM Source_Data s
    ORDER BY Year DESC
    /will give
         YEAR YEAR_VALUE ORIGINAL_AMOUNT CUMULATIVE_SUM YEAR_QUOTA
         2006        600            1200            600        600
         2005        500            1200           1100        500
         2004        400            1200           1500        100
         2003        300            1200           1800          0
         2002        200            1200           2000          0
         2001        100            1200           2100          0You can add different conditions (PARTITION BY ..)
    Hope this helps
    Max

  • Should I use Analytic functions ?

    Hello,
    I have a table rci_dates with the following structure (rci_id,visit_id,rci_name,rci_date).
    A sample of data in this table is as given below.
    1,101,'FIRST VISIT', '2010-MAY-01',
    2,101,'FIRST VISIT', '2010-MAY-01'
    3,101,'FIRST VISIT', '2010-MAY-01'
    4,101,'FIRST VISIT', '2010-MAY-01'
    5,102,'SECOND VISIT', '2010-JUN-01',
    6,102,'SECOND VISIT', '2010-JUN-01'
    7,102,'SECOND VISIT', '2010-JUN-01'
    8,102,'SECOND VISIT', '2010-JUL-01'
    I want to write a query which returns me the records which are similar to the record with rc_id =8 since the rci_date is different within the visit_id 102. Where as in Visit_id 101 the rci_dates are all same so it should not be displayed in the output returned by my query.
    How can I do this ? Should I be using analytic functions. Can someone please let me know.
    Thanks

    ok i have created the table and inserted the data. but it appears that the data are the output you are expecting, they all the same visit_id.
    SQL> CREATE TABLE RCI
      2  (RCI_ID NUMBER(10) NOT NULL,
      3   VISIT_ID NUMBER(10) NOT NULL,
      4   RCI_NAME VARCHAR2(20 BYTE) NOT NULL,
      5   DCI_DATE VARCHAR2(8 BYTE));
    Table created
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14876540, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14876640, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14876740, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14876840, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14876940, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877040, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877140, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877240, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877240, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877640, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877740, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877840, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877940, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878040, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878140, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878240, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878340, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878440, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878540, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877640, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14877740, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878340, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878540, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 17418240, 12140, 'SCREENING', '20000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 17418340, 12140, 'SCREENING', '20000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 17418440, 12140, 'SCREENING', '20000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14878240, 12140, 'SCREENING', '20000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 18790240, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 21724540, 12140, 'SCREENING', '19000101');
    1 row inserted
    SQL> INSERT INTO RCI ( RCI_ID, VISIT_ID, RCI_NAME, DCI_DATE ) VALUES ( 14876540, 12140, 'SCREENING', '20091015');
    1 row inserted
    SQL> commit;
    Commit complete
    SQL> select * from rci;
         RCI_ID    VISIT_ID RCI_NAME             DCI_DATE
       14876540       12140 SCREENING            19000101
       14876640       12140 SCREENING            19000101
       14876740       12140 SCREENING            19000101
       14876840       12140 SCREENING            19000101
       14876940       12140 SCREENING            19000101
       14877040       12140 SCREENING            19000101
       14877140       12140 SCREENING            19000101
       14877240       12140 SCREENING            19000101
       14877240       12140 SCREENING            19000101
       14877640       12140 SCREENING            19000101
       14877740       12140 SCREENING            19000101
       14877840       12140 SCREENING            19000101
       14877940       12140 SCREENING            19000101
       14878040       12140 SCREENING            19000101
       14878140       12140 SCREENING            19000101
       14878240       12140 SCREENING            19000101
       14878340       12140 SCREENING            19000101
       14878440       12140 SCREENING            19000101
       14878540       12140 SCREENING            19000101
       14877640       12140 SCREENING            19000101
       14877740       12140 SCREENING            19000101
       14878340       12140 SCREENING            19000101
       14878540       12140 SCREENING            19000101
       17418240       12140 SCREENING            20000101
       17418340       12140 SCREENING            20000101
       17418440       12140 SCREENING            20000101
       14878240       12140 SCREENING            20000101
       18790240       12140 SCREENING            19000101
       21724540       12140 SCREENING            19000101
       14876540       12140 SCREENING            20091015
    30 rows selected
    SQL> -- using the sample similar code that i have previously posted it returned all the rows.
    SQL> select rci.*
      2    from rci
      3   where rci.visit_id in (select r1.visit_id
      4                            from (select rci.visit_id,
      5                                         count(*) over (partition by rci.visit_id, rci.dci_date order by rci.visit_id) rn
      6                                    from rci) r1
      7                            where r1.rn = 1)
      8  order by rci.rci_id;
         RCI_ID    VISIT_ID RCI_NAME             DCI_DATE
       14876540       12140 SCREENING            20091015
       14876540       12140 SCREENING            19000101
       14876640       12140 SCREENING            19000101
       14876740       12140 SCREENING            19000101
       14876840       12140 SCREENING            19000101
       14876940       12140 SCREENING            19000101
       14877040       12140 SCREENING            19000101
       14877140       12140 SCREENING            19000101
       14877240       12140 SCREENING            19000101
       14877240       12140 SCREENING            19000101
       14877640       12140 SCREENING            19000101
       14877640       12140 SCREENING            19000101
       14877740       12140 SCREENING            19000101
       14877740       12140 SCREENING            19000101
       14877840       12140 SCREENING            19000101
       14877940       12140 SCREENING            19000101
       14878040       12140 SCREENING            19000101
       14878140       12140 SCREENING            19000101
       14878240       12140 SCREENING            19000101
       14878240       12140 SCREENING            20000101
       14878340       12140 SCREENING            19000101
       14878340       12140 SCREENING            19000101
       14878440       12140 SCREENING            19000101
       14878540       12140 SCREENING            19000101
       14878540       12140 SCREENING            19000101
       17418240       12140 SCREENING            20000101
       17418340       12140 SCREENING            20000101
       17418440       12140 SCREENING            20000101
       18790240       12140 SCREENING            19000101
       21724540       12140 SCREENING            19000101
    30 rows selected
    SQL> just as what frank have said it will be helpful if you post a sample output based on the original posting, that is in the first posting you have.

  • SQL using analytical function

    Hi all,
    I want an help in creating my SQL query to extract the data described below:
    I have one table example test containing data like below:
    ID     Desc     Status
    1     T1          DEACTIVE
    2     T2          ACTIVE
    3     T3          SUCCESS
    4     T4          DEACTIVE
    The thing i want to do is selecting all lines with ACTIVE status in this table but is there is no ACTIVE status, my query will give me the last line with DEACTIVE status.
    Can I do this in one query by using analytical function for example, if yes can yiu help me on thaht query.
    regards,
    Raluce

    Hi, Raluce,
    Here's one way to do that:
    WITH got_r_num AS
        SELECT  deptno, ename, job, hiredate
        ,       ROW_NUMBER () OVER ( PARTITION BY  deptno
                                     ORDER BY      job
                                     ,             hiredate  DESC
                                   )  AS r_num
        FROM    scott.emp
        WHERE   job  IN ('ANALYST', 'CLERK')
    SELECT     deptno, ename, job, hiredate
    FROM       got_r_num
    WHERE      job     = 'ANALYST'
    OR         r_num   = 1
    ORDER BY   deptno
    Since I don't have a sample version of your table, I used scott.emp to illustrate.
    Output:
        DEPTNO ENAME      JOB       HIREDATE
            10 MILLER     CLERK     23-JAN-82
            20 SCOTT      ANALYST   19-APR-87
            20 FORD       ANALYST   03-DEC-81
            30 JAMES      CLERK     03-DEC-81
    This query finds all ANALYSTs in each department, regardless of how many there are.  (Deptno 20 happens to have 2 ANALYSTs.)  If there is no ANALYST in a department, then the most recently hired CLERK is included.  (Deptnos 10 and 30 don't have any ANALYSTs.)
    This "partitions", or sub-divides, the table into separate units, one for each department.  In the problem you posted, it looks like you want to operate in the entire table, without sub-dividing it in any way.  To do that, just omit the PARTITION BY clause in the analytic ROW_NUMBER function, like this:
    WITH got_r_num AS
        SELECT  deptno, ename, job, hiredate
        ,       ROW_NUMBER () OVER ( --  PARTITION BY  deptno
                                     ORDER BY      job
                                     ,             hiredate  DESC
                                   )  AS r_num
        FROM    scott.emp
        WHERE   job  IN ('ANALYST', 'CLERK')
    SELECT     deptno, ename, job, hiredate
    FROM       got_r_num
    WHERE      job     = 'ANALYST'
    OR         r_num   = 1
    ORDER BY   deptno

  • Need help to join two tables using three joins, one of which is a (between) date range.

    I am trying to develop a query in MS Access 2010 to join two tables using three joins, one of which is a (between) date range. The tables are contained in Access. The reason
    the tables are contained in access because they are imported from different ODBC warehouses and the data is formatted for uniformity. I believe this cannot be developed using MS Visual Query Designer. I think writing a query in SQL would be suiting this project.
    ABCPART links to XYZPART. ABCSERIAL links to XYZSERIAL. ABCDATE links to (between) XYZDATE1 and ZYZDATE2.
    [ABCTABLE]
    ABCORDER
    ABCPART
    ABCSERIAL
    ABCDATE
    [ZYXTABLE]
    XYZORDER
    XYZPART
    XYZSERIAL
    XYZDATE1
    XYZDATE2

    Thank you for the looking at the post. The actual table names are rather ambiguous. I renamed them so it would make more sense. I will explain more and give the actual names. What I do not have is the actual data in the table. That is something I don't have
    on this computer. There are no "Null" fields in either of the tables. 
    This table has many orders (MSORDER) that need to match one order (GLORDER) in GLORDR. This is based on MSPART joined to GLPART, MSSERIAL joined to GLSERIAL, and MSOPNDATE joined if it falls between GLSTARTDATE and GLENDDATE.
    [MSORDR]
    MSORDER
    MSPART
    MSSERIAL
    MSOPNDATE
    11111111
    4444444
    55555
    2/4/2015
    22222222
    6666666
    11111
    1/6/2015
    33333333
    6666666
    11111
    3/5/2015
    This table has one order for every part number and every serial number.
    [GLORDR]
    GLORDER
    GLPART
    GLSERIAL
    GLSTARTDATE
    GLENDDATE
    ABC11111
    444444
    55555
    1/2/2015
    4/4/2015
    ABC22222
    666666
    11111
    1/5/2015
    4/10/2015
    AAA11111
    555555
    22222
    3/2/2015
    4/10/2015
    Post Query table
    GLORDER
    MSORDER
    GLSTARTDATE
    GLENDDATE
    MSOPNDATE
    ABC11111
    11111111
    1/2/2015
    4/4/2015
    2/4/2015
    ABC22222
    22222222
    1/5/2015
    4/10/2015
    1/6/2015
    ABC22222
    33333333
    1/5/2015
    4/10/2015
    3/5/2015
    This is the SQL minus the between date join.
    SELECT GLORDR.GLORDER, MSORDR.MSORDER, GLORDR.GLSTARTDATE, GLORDR.GLENDDATE, MSORDR.MSOPNDATE
    FROM GLORDR INNER JOIN MSORDR ON (GLORDR.GLSERIAL = MSORDR.MSSERIAL) AND (GLORDR.GLPART = MSORDR.MSPART);

  • Need a function to calculate employee attendance data for a given period

    need a function to calculate employee attendance data for a given period
    as
    Working days,
    CL ,
    SL,
    PL,
    LWP
    regards,
    Gaurav Sood.

    Issue resolved

  • Maybe you are looking for

    • Usb 6009:connecting the sensor and motor

      Hi there, I am new to the labview also the usb-6009. I want to know if I can connect my sensor to the device. The output of the sensor is either analog voltage, pulse width or serial.If I want to use the AN pin, can I just connect the wire to the ADC

    • Labview VI with Excel toolkit report

      In SignalExpress, I have to analyze data and save this analysis in Excel Workbook, to do this, i reuse VI for the analysis, and use Report Generation 1.1.1 toolkit for Office. But an error appear : Error (97): Unknown System Error in Excel_Get_Proper

    • Help with Dreamweaver CS5 spry menus. Menu is not dropping down in IE7.

      Hello. We recently upgraded from GoLive CS3 to Dreamweaver CS5. Wow! This has been a big change for us. We are having trouble with a website that we are building, specifically the Spry Menu drop downs not appearing correctly in IE7 and older. While t

    • Duke Nukem 3d and G1 iPod touch

      Does any one else have this same problem. When you go to buy the game it states that you cannot buy it due to the requirement of a microphone. When I played Duke Nukem 3d on my PC I don't remember that there was a microphone function. If any one know

    • Selection screen display after role menu selection

      Hi, I have strange situation: - running a query on the WEB from Query Designer 3.5 first display a selection screen and then the data - what is OK or expected - but we created an application in WAD with just role menu - if we pick the same query, fro