Interview with case/when & sum() over (partition) producing unexpected lines

Since some time ago, I asked a question in this forum on an unusual problem of join and subtract ( subtract the total periods of highest level duration ). I had what seemed like a work request. So far, I could not really use it. Now that I'm looking closer results, I think that there is something wrong with it, but I can't understand why it's happening.

Using the definition of the table of the original question, the following simple query shows a special extract of the data I'm looking at.

Select duration, event_type, start_time, code_range, request_id from MYTABLE where REQUEST_ID = 'abc '.

This translates into the following lines (separate columns by ' / '):

START_TIME/REQUEST_ID/EVENT_TYPE/CODE_RANGE/DURATION
2010-11-12 01:42:04.0/abc/Junk/publicEntryPoint/2,003
2010-11-12 01:42:04.0/abc/Junk/webServiceCall/947
2010-11-12 01:42:04.0/abc/Junk/webServiceCall/969

Another similar request with REQUEST_ID = 'def' means:

START_TIME/REQUEST_ID/EVENT_TYPE/CODE_RANGE/DURATION
2010-11-12 00:22:13.0/def/junk/webServiceCall/788
2010-11-12 00:22:13.0/def/junk/webServiceCall/1,128
2010-11-12 00:22:13.0/def/junk/publicEntryPoint/2,003

What follows is an excerpt simplified query I have a problem with:

Select value start_time request_id event_type, code_range, duration, case code_range
When "publicEntryPoint" then length * 2 - sum (duration) over (partition by request_id)
of another-1
end inner_duration from MYTABLE where EVENT_TYPE = 'spam' and trunc (START_TIME) = to_date('2010-11-12','yyyy-mm-dd')
and rownum < 1000;

Notice the couple of unconventional functions used here, the ' case/when' and 'sum() over (partition).

This property returns a bunch of lines (count: 999), but here are the two with the particular REQUEST_ID values:

START_TIME/REQUEST_ID/EVENT_TYPE/CODE_RANGE/DURATION/INNER_DURATION
2010-11-12 01:42:04.0/abc/junk/publicEntryPoint/2,003/2,003
2010-11-12 00:22:13.0/def/junk/publicEntryPoint/2,003/87

The second line is correct. The first line has an unexpected value of INNER_DURATION of 2003. It should be 87 as the second row. I don't understand why this is happening.

I think that 'and rownum '.<1000" must="" be="" the="" problem.="" it="" must="" be="" excluding="" some="" of="" the="" rows="" needed="" for="" the="" sum.="" the="" analytic="" function="" will="" be="" applied="" after="" this="" condition--see="" the="" sql="">

Analytical functions are the last set of operations performed in a query, except for the
final ORDER BY clause. Every joint and every WHERE, GROUP BY and HAVING clauses are
completed before the analytical functions are processed

Have you tried the query without this condition?

Kind regards
Bob

Tags: Database

Similar Questions

  • Subselect with clause with and nvl() with case when as 2nd argument does not work

    I get an error for this one

    Select)

    with x

    (select 1 of the double)

    Select

    NVL (x.a, cases where x.a is null then fine otherwise 3 2)

    the double)

    of the double

    Error is:

    ORA-00904: 'X '. "' A ': invalid identifier

    ... related to the use of x.a in an expression box as the 2nd argument of nvl (...)

    Rgds,

    Frank

    Hello

    Maybe like this?

    Select)

    with x

    (select 1 of the double)

    Select

    NVL (x.a, case when x.a is null, then Itf_Pkg.Itf_Null_Value ("x.a', 'a null value'") or 3 end)

    X)

    of the double

  • Problem with case when try to alter the query from siimple

    Hello PL/SQL gurus and Experts.

    I'm stuck with a question (can be simple), but not gettings all headsway.
    select 365/day_num_yr Anul_Fact from Date where date_dt = trunc(sysdate -1) 
    value returns is as - 1.46

    need to write it in the form of case (I have to multiply it to some other outer query), I want to store variable ina and then use the same in an outside -.
    but when use the following syntax, then it always returns 0 and not the same output returned by the query above without the scabbard.
    select (case when date_dt =trunc(sysdate -1) then 365/day_num_yr else 0 END) Anul_Fact 
    Help kindly, I appericate your time and effort in advance.

    user555994 wrote:
    Problem is that I do not get the output as 1.46, even the output is coming like the 0 only if using the query - next

    select /*date_dt, sysdate - 1 prev_dt, trunc(sysdate - 1) trunc_prev_dt,*/
    case when date_dt = trunc(sysdate -1) then  365/day_num_yr
    else 0
    end num_day
    from date_dim;
    

    Completely, which seems to be a question of DATA. Have you checked if the table contains data for DATE_DT = SYSDATE - 1? Can you check if the data stored do not have hours and Minutes stored?

    Although I have provided examples of data, which is the same as the data in my main table and once I used the previous solution you provided and then also gives the result as same as those mentioned by you.

    I think it's something like -

    select date_dt, sysdate - 1 prev_dt, trunc(sysdate - 1) trunc_prev_dt,
    case when date_dt = trunc(sysdate -1) then  366/day_num_yr where day_num_yr=(select day_num_yr from date_dim where date_dt = trunc(sysdate -1))
    else 0
    end num_day
    from date_dim;
    

    Once we get the day_num_yr then he deviding by 366/day_num_yr :(
    but he does not like throwing an error ORA-95 - missing keyword

    Yes, it does not work

    -case when date_dt = trunc (sysdate-1) then 366/day_num_yr where day_num_yr = (select day_num_yr from the date_dim where date_dt = trunc (sysdate-1))

    due to a syntax of alien.
    I don't think that you really need. I already said, with the data in your Table, you will be having only * 1 * record with a Non - zero value. Thus, simply apply a filter to extract the corresponding record SYSDATE - 1 and you should get an output which is Non-zero. If you apply a where predicate, then would not need you a CASE statement. You can directly use something like below:

    select date_dt, sysdate - 1 prev_dt, trunc(sysdate - 1) trunc_prev_dt,
           365 / day_num_yr num_day
      from t4
     where date_dt = trunc(sysdate - 1);
    

    Published by: Jen K, September 7, 2012 16:00

  • Optimize SQL with case-when-other

    Hello

    try to categorize DateValue into 3 groups
    1. effective: current month
    2. for a YEAR: between January and last month of the current year
    3. for a YEAR: between January and last month of the last year

    I have a feeling that my SQL could be much shorter and faster. I would be grateful for professional advice...

    -case when TO_NUMBER ((TO_CHAR (DOCUMENT_TIMESTAMP, 'YYYY') |)) To_char (DOCUMENT_TIMESTAMP, 'MM'))) = TO_NUMBER (TO_CHAR (sysdate, 'YYYY') |) To_char (sysdate, 'MM'))
    can 'real '.
    -FOR A YEAR
    When TO_NUMBER ((TO_CHAR (DOCUMENT_TIMESTAMP, 'YYYY') |)) To_char (DOCUMENT_TIMESTAMP, 'MM'))) between TO_NUMBER (TO_CHAR (sysdate, 'YYYY') |) (' 01') and TO_NUMBER (TO_CHAR (sysdate, 'YYYY') |) To_char (sysdate, 'MM'))-1
    then "CDA".
    -PYTD
    When TO_NUMBER ((TO_CHAR (DOCUMENT_TIMESTAMP, 'YYYY') |)) To_char (DOCUMENT_TIMESTAMP, 'MM'))) between TO_NUMBER (TO_CHAR(sysdate, 'YYYY')-1). ' 01' and TO_NUMBER (TO_CHAR(sysdate, 'YYYY')-1 |) To_char (sysdate, 'MM'))-1
    then "PYTD".
    else "Others" end up as ABC

    Hello

    I find trunc to be more readable:

    SQL> WITH DATA AS (
      2     SELECT SYSDATE d FROM dual UNION ALL
      3     SELECT add_months(SYSDATE, -12) FROM dual UNION ALL
      4     SELECT DATE '2009-01-01' FROM dual
      5  )
      6  SELECT to_char(d, 'dd-mon-yyyy') "Date",
      7         CASE
      8            WHEN trunc(d, 'month') = trunc(SYSDATE, 'month') THEN
      9             'Actual'
     10            WHEN trunc(d, 'year') = trunc(SYSDATE, 'year') AND d < sysdate THEN
     11             'YTD'
     12            WHEN trunc(d, 'year') = add_months(trunc(SYSDATE, 'year'), -12) THEN
     13             'PYTD'
     14         END "Case"
     15    FROM DATA
     16  ;
    
    Date              Case
    ----------------- ------
    10-jun-2009       Actual
    10-jun-2008       PYTD
    01-jan-2009       YTD
    

    Kind regards

    --
    Vincent

    Published by: user11163377 on June 10, 2009 02:12 - corrected the CDA column

  • Need help with CASE When statement in a Where Clause

    So I have a SQL (simplified for this forum)

    Select t1.*
    from table1, table2 t2 t1
    where t1.field1 = t2.field1
    and when t1.field2 is null then trunc (sysdate) < = trunc (t1.date1 + 17)
    of another trunc (sydate) > = end of trunc (t2.date2 + t2.date3)

    I end up getting an error ORA-00905: lack of keyword

    I'm sure that I just got something here involved.

    You can not make the comparison within the statement underlying case like this. Assuming you have appropriate data types, something like this should work

    Select t1.*
    from table1 t1, table2 t2
    where t1.field1 = t2.field1
      and ((t1.field2 is null and
            trunc(sysdate) <= trunc(t1.date1 + 17)) or
           trunc(sydate) > = trunc(t2.date2 + t2.date3))
    

    John

  • Helps with the sum on partition

    Hi all

    This is my sample data:

    create table general(
    general_id number,
    general_type nvarchar2(10),
    start_year number,
    end_year number,
    fy number,
    fy_value number
    );
    
    insert into general(general_id, general_type, start_year, end_year, fy, fy_value)
    values (1, 'data 1', 2009, 2013, 2010, 10);
    insert into general(general_id, general_type, start_year, end_year, fy, fy_value)
    values (1, 'data 1', 2009, 2013, 2013, 20);
    insert into general(general_id, general_type, start_year, end_year, fy, fy_value)
    values (2, 'data 2', 2010, 2014, 2010, 5);
    insert into general(general_id, general_type, start_year, end_year, fy, fy_value)
    values (2, 'data 2', 2010, 2014, 2013, 15);
    
    SELECT general_id, general_type, fy,
      sum(fy_value) over (partition by general_id, general_type order by fy) sum_fy_value
    FROM general
    

    My results:

    
    GENERAL_ID    GENERAL_TYPE    FY    SUM_FY_VALUE
    1    data 1    2010    10
    1    data 1    2013    30
    2    data 2    2010    5
    2    data 2    2013    20
    

    How can I complete the sum of the missing years (with leading zeros), from my year start and end?

    Example of final results:

    GENERAL_ID    GENERAL_TYPE    FY    SUM_FY_VALUE
    1    data 1    2009    0
    1    data 1    2010    10
    1    data 1    2011    10
    1    data 1    2012    10
    1    data 1    2013    30
    2    data 2    2010    5
    2    data 2    2011    5
    2    data 2    2012    5
    2    data 2    2013    20
    2    data 2    2014    20
    

    Oracle Database 11g - 11.2.0.4.0

    Thanks in advance.

    SQL> with t
      2  as
      3  (
      4   select general_id
      5        , general_type
      6        , start_year + (level-1) fy
      7     from (
      8            select distinct general_id
      9                 , general_type
     10                 , start_year
     11                 , end_year
     12              from general
     13          )
     14  connect
     15       by level <= end_year - start_year + 1
     16      and prior general_id = general_id
     17      and prior dbms_random.value is not null
     18  )
     19  select t.general_id
     20       , t.general_type
     21       , t.fy
     22       , sum(nvl(g.fy_value, 0)) over(partition by t.general_id order by t.fy) sum_fy_value
     23    from t
     24    left join
     25         general g
     26      on t.general_id = g.general_id
     27     and t.fy         = g.fy
     28   order
     29      by general_id
     30       , fy;
    
    GENERAL_ID GENERAL_TY         FY SUM_FY_VALUE
    ---------- ---------- ---------- ------------
             1 data 1           2009            0
             1 data 1           2010           10
             1 data 1           2011           10
             1 data 1           2012           10
             1 data 1           2013           30
             2 data 2           2010            5
             2 data 2           2011            5
             2 data 2           2012            5
             2 data 2           2013           20
             2 data 2           2014           20
    
    10 rows selected.
    

    Note: I must say that it is one of these well posed the question, which we do not often here. I appreciate you providing sample data and expected outcomes in a well-formatted way and also provides the oracle version 4-digit.

  • Can I change the icon of the cursor when hover over one active link with another?

    Can I change the icon of the cursor when hover over one active link with another?

    Muse does not natively support, but all you need to do to make it work is on your page, add properties in the head content:

    Where "value" is the cursor you want for example for a cross-shaped cursor...

  • Helps with the instruction WHEN SUM

    I have the following code which works without a problem. However, I need to add an extra parameter. I need to SUM when the name of the month is > 0 and less than 37. How can I add the > option 0?

    Thank you!



    , sum (case when month_name < 37 then qty_used 0 otherwise end) M_0

    Hello

    847497 wrote:
    I have the following code which works without a problem. However, I need to add an extra parameter. I need to SUM when the name of the month is > 0 and less than 37. How can I add the > option 0?

    Thank you!

    sum (case when month_name< 37="" then="" qty_used="" else="" 0="" end)="">

    Conditions in a CASE expression can be compound conditions, linked by AND or or, as the conditions in a WHERE clause.

    SUM ( CASE
              WHEN  month_name  >  0
           AND   month_name  < 37     THEN  qty_used
                                     ELSE  0
          END
        )          AS m_0
    
  • error when using ' select case-sensitive when sum() group by»

    SELECT REGION_CODE
    REGION_DESC
    CASE WHEN END OF SUM (UP_SMS_TIMES) BETWEEN T2.SMS_MIN AND T2.SMS_MAX THEN T2.SMS_LVL_CODE
    OF PMID. TB_MID_PAR_EXT_USER_MON T1, EDCP. TB_CDE_SMS_LVL T2
    WHERE DEAL_DATE = '200811'
    REGION_CODE GROUP, REGION_DESC

    {color: #ff0000} error: ORA-00979: not a GROUP BY expression

    {color} {color: #000000} How can I fix the error, thanks {color}

    Hello

    Try this query:

    SELECT t1.region_code,
    T1.region_desc,
    MAX (t2.sms_lvl_code) AS sms_lvl
    FROM (SELECT region_code,
    region_desc,
    SUM (up_sms_times) up_sms_times
    OF tb_mid_par_ext_user_mon
    WHERE deal_date = '200812'
    AND up_sms_times > 0
    Region_code GROUP,
    region_desc T1),
    tb_cde_sms_lvl t2
    WHERE the t1.up_sms_times BETWEEN t2.sms_min AND t2.sms_max
    T1.region_code GROUP, t1.region_desc

    Kind regards

    Shandy Hidayat

  • SUM on &amp; Partition BY... Try to get the correct total run.

    running: Oracle XE 11


    Hi all, I am using the analytical function of PARTITION BY to get my total race for a report. (in this case the bank balance)


    SUM (bank_stmts.amount) OVER (PARTITION BY bank_stmts.account_ID ORDER BY bank_stmts.tx_date, bank_stmts.id)


    I add a balance initial in the table at the beginning of the year, and everything works fine when I select on the recordings of the whole years...


    However, I need to interview a subset of the report, i.e. one month, or a selection of documents, rather than year-round. But I still want to see the total calculated for the whole year on the report, not a total operating for the subset of records. I'm not sure how to do that because when I select a subset, it totals only the subset...


    I see that there are a number of clauses on the analytical function, especially BETWEEN the LINES or RANGE, but my assumption is that these still only works on surveyed lines and not any of the table...


    My way of thinking for the moment, is that patients have to calculate and enter the total in the table when the row is inserted, probably via a trigger. However, I didn't keep far from...


    Kind regards

    Richard

    SQL > with t as)
    2. Select ename,
    3                     job,
    4 hiredate,
    5 sum (sal) over (partition by deptno arrested by hiredate) running_total_sal
    6 of PEM
    7            )
    8 select
    9 t
    10 order by hiredate
    11.

    HIREDATE RUNNING_TOTAL_SAL EMPLOYMENT ENAME
    ------ --------- --------- -----------------
    SMITH, CLERK DECEMBER 17, 80 800
    ALLEN SALESMAN FEBRUARY 20 81 1600
    WARD 22 FEBRUARY SALESMAN 81 2850
    MANAGER OF JONES 2 APRIL 81 3775
    BLAKE MANAGER MAY 1, 81 5700
    CLARK MANAGER JUNE 9, 81 2450
    SELLER OF 7200 08 - SEP - 81 TURNER
    MARTIN SELLER 28-SEP-81 8450
    PRESIDENT KING NOVEMBER 17 81-7450
    JAMES CLERK 9400 3 DECEMBER 81
    DECEMBER 3, 81 FORD ANALYST 6775

    HIREDATE RUNNING_TOTAL_SAL EMPLOYMENT ENAME
    ------ --------- --------- -----------------
    MILLER COMMITTED JANUARY 23, 82 8750
    SCOTT, ANALYST APRIL 19 87 9775
    ADAMS, CLERK MAY 23, 87 10875

    14 selected lines.

    SQL > with t as)
    2. Select ename,
    3                     job,
    4 hiredate,
    5 sum (sal) over (partition by deptno arrested by hiredate) running_total_sal
    6 of PEM
    7            )
    8 select
    9 t
    10 where hiredate > = date ' 1981-01-01'
    11 and hiredate<  date="">
    12 order by hiredate
    13.

    HIREDATE RUNNING_TOTAL_SAL EMPLOYMENT ENAME
    ------ --------- --------- -----------------
    ALLEN SALESMAN FEBRUARY 20 81 1600
    WARD 22 FEBRUARY SALESMAN 81 2850
    MANAGER OF JONES 2 APRIL 81 3775
    BLAKE MANAGER MAY 1, 81 5700
    CLARK MANAGER JUNE 9, 81 2450

    SQL >

    SY.

  • Interview with incrementing field which resets on certain conditions?

    I have this query which gives a history of the units that is painted in our production process and flags when there is a change in color.
    select LINE_DESCR, PAINT_TIME, COLOR, lag(COLOR) over (partition by LINE_DESCR order by PAINT_TIME) PREV_COLOR,
    case when COLOR != lag(COLOR) OVER (PARTITION by LINE_DESCR ORDER BY PAINT_TIME) then 1 else 0 end COLOR_CHANGE
    from UNIT_PAINTINGS up, UNIT_PAINT_LINES upl, UNIT_INFO ui
    where up.LINE_ID = upl.ID
    and up.UNIT_ID = ui.ID
    and PAINT_TIME between sysdate - 1 and sysdate
    That gives me results that look like this.
    LINE_DESCR  PAINT_TIME          COLOR     PREV_COLOR COLOR_CHANGE                           
    IPP 1       4/9/2013 16:06:53   A82       A52        1
    IPP 1       4/9/2013 16:08:46   354       A82        1                            
    IPP 1       4/9/2013 16:10:21   475       354        1                               
    IPP 1       4/9/2013 16:12:05   475       475        0                              
    IPP 1       4/9/2013 16:15:25   475       475        0                                    
    IPP 1       4/9/2013 16:17:01   475       475        0                                
    IPP 1       4/9/2013 16:18:55   475       475        0                               
    IPP 1       4/9/2013 16:20:44   668       475        1                               
    IPP 1       4/9/2013 16:22:32   475       668        1                                
    IPP 1       4/9/2013 16:24:26   475       475        0                             
    I want to add a count of the number of units between color changes, which will be increments when COLOR_CHANGE = 0 and back to 1 when COLOR_CHANGE = 1, like this:
    LINE_DESCR  PAINT_TIME          COLOR     PREV_COLOR COLOR_CHANGE PAINTED_UNITS                           
    IPP 1       4/9/2013 16:06:53   A82       A52        1            1                                      
    IPP 1       4/9/2013 16:08:46   354       A82        1            1                          
    IPP 1       4/9/2013 16:10:21   475       354        1            1                         
    IPP 1       4/9/2013 16:12:05   475       475        0            2                         
    IPP 1       4/9/2013 16:15:25   475       475        0            3                         
    IPP 1       4/9/2013 16:17:01   475       475        0            4                         
    IPP 1       4/9/2013 16:18:55   475       475        0            5                         
    IPP 1       4/9/2013 16:20:44   668       475        1            1                         
    IPP 1       4/9/2013 16:22:32   475       668        1            1                         
    IPP 1       4/9/2013 16:24:26   475       475        0            2
    Suggestions on how to do this better?

    Thank you
    Farida

    Hi, Farida,

    Maybe:

    WITH     got_grp_num     AS
    (
         select  LINE_DESCR, PAINT_TIME, COLOR
         ,      lag( COLOR) over ( partition by  LINE_DESCR
                                        order by        PAINT_TIME
                          )      AS PREV_COLOR
            ,       case
                  when COLOR != lag (COLOR) OVER ( PARTITION by  LINE_DESCR
                                                              ORDER BY          PAINT_TIME
                                     )
                  then 1
                  else 0
                 end               AS COLOR_CHANGE
         ,     ROW_NUMBER () OVER ( PARTITION BY  line_descr
                                   ORDER BY          paint_time
                           )
               -     ROW_NUMBER () OVER ( PARTITION BY  line_descr
                                         ,                    color
                                   ORDER BY          paint_time
                           )    AS grp_num
            from      UNIT_PAINTINGS   up
         ,      UNIT_PAINT_LINES upl
         ,      UNIT_INFO       ui
         where      up.LINE_ID       = upl.ID
         and     up.UNIT_ID      = ui.ID
         and      PAINT_TIME       between  sysdate - 1
                              and        sysdate
    )
    SELECT       line_descr, paint_time, color
    ,       prev_color, color_change
    ,       ROW_NUMBER () OVER ( PARTITION BY  line_descr
                                 ,           color
                          ,          grp_num
                          ORDER BY          paint_time
                               )      AS painted_units
    FROM      got_grp_num
    ;
    

    If you would care to post CREATE TABLE and INSERT statements for your sample data, and then I could test this.

    Looks like the painted_units can be generated by the analytical ROW_NUMBER function. Obviously, we want to ORDER BY paint_tme, but what can we PARTITION BY? Line_desc? Yes, we are a numbrs o setting separately for each line_desc, but we may need several sets of ROW_NUMBERs for the same lin_desc. Can you color and PARTITION BY line_descr? Yes, a set of numbers will apply only to a particular combination of line_descr and color, but what happens if the stats of color as a thing, then changes and modifications to the original color? We need a whole separate ROW_NUMBERs for each of these groups. That's exactly what grp_num is. (Notice the got_grp_num of the subquery is just your request of moose, more than an additional column.) The main request is noting except drifting painted units. We have need of a subquery, because the analytical functions that derive from painted_units depends on the grp_num and grp_num is itself the result of an analytic function and a function anlaytic cannot be dependent on another calculated the same subsidiary query.

    See for an explanation of the technique Difference sets used to calculate the grp_num, {message: id = 9953384} and/or {message identifier: = 9957164}

  • Sum over time

    Hello

    I'm doing something that I think is quite a common request, but after scratching my head and browsing the web I am still not close to a solution.

    I am running:
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi

    I'm looking to summarize a set of values, taking into account the two parent grouping and start and end dates.
    I use for the parent of grouping:

    + Sum ([value]) over (Partition by order [Parent] [parent], [Child]) +.

    I was hoping to expand that AMOUNT to manage also the start and end dates, so the end result would contain a sum of the values for each different period of time.

    For example, using the data below I try to sum up the prices of the components of a car over time:

    line, product, component, rate, start date, end date
    1, car, chassis, 180, 01/01/2000, 31/12/2009
    2, car, chassis, 200, 01/01/2010, 01/01/2050
    3, car, engine, 100, 01/01/2000, 01/01/2050


    Notice that there is a price for "Chassis" of item change, so the output, I'm looking for is:


    line, product, component, rate, start date, end date, sum
    1, car, chassis, 180, 280 01/01/2000, 31/12/2009,
    2, car, engine, 100, 280 01/01/2000, 31/12/2009,
    3, car, chassis, 200, 01/01/2010, 01/01/2050, 300
    4, car, engine, 100, 01/01/2010, 01/01/2050, 300


    But in reality, everything I need is:

    Row, product, start date, end date, sum
    1, car, 01/01/2000, 31/12/2009, 280
    2, cars, 01/01/2010, 01/01/2050, 300

    Preference the query would be a view instead of a stored procedure, and he must be able to manage many 'products', 'components' and start and end dates.


    All help most appreciated and if need more info, please let me know.

    Thank you
    Julian

    Hi, Julian,.

    I think I understand.
    You want to use the lump SUM, not the analytical SUM. The analytical function you would give a total for the entire product, but would keep the individual lines for each component. But you don't want individual lines for each component; you want to just one line for each product and the period. The tricky thing with this problem is to set a period. In the following query, a new period for a given product begins when there is a start_date or an end_date for this product, which is calculated in the sub_query called periods.

    The following subquery, active_ratews, see what rate applied during this period, seeing the lines in product_rates overlap with the lines in periods. Two overlap if everyone will start before the other ends. If it's not obvious to you (and it is of course obvious to me when I heard it), then look at it this way: two ranges are not overlapping if (and only if) one end before another begins.

    The result of the ios active_rates close enough of what you posted as intermediate results. The main request that added all the lines for the same product and timely.

    WITH   period_start_points          AS
    (
         SELECT  product
         ,     start_date
         FROM     product_rates
        UNION
            SELECT  product
         ,     end_date + 1     AS start_date
         FROM     product_rates
    )
    ,     periods          AS
    (
         SELECT  product
         ,     start_date
         ,     LEAD (start_date) OVER ( PARTITION BY  product
                                          ORDER BY      start_date
                               )          AS end_date
         FROM    period_start_points
    )
    ,     active_rates     AS
    (
         SELECT     p.product
         ,     p.start_date
         ,     p.end_date - 1     AS end_date
         ,     r.component
         ,     r.rate
         FROM     periods          p
         JOIN     product_rates     r  ON     p.product     = r.product
                           AND     p.start_date     <= r.end_date
                           AND     r.start_date     <  p.end_date
    )
    SELECT    ROW_NUMBER () OVER ( ORDER BY  product
                                 ,           start_date
                        )  AS row_n
    ,       product, start_date, end_date
    ,       SUM (rate)             AS total_rate
    FROM       active_rates
    GROUP BY  product, start_date, end_date
    ORDER BY  product, start_date
    ;
    

    Viguierkevin wrote: in addition, a quick query to improve my ads - how indent without doing ittallic of text, and how to code a different font?

    This site normally does not display multiple spaces in a row.
    Whenever you post the text formatted (for example, the results of the query) on this site, type the 6 characters:

    \

    (small letters only, inside curly brackets) before and after each section of formatted text, to preserve spacing.  Everything between the \
    

    tags appear in a police fixed-width.

    Published by: Frank Kulash, January 4, 2012 14:09
    Added explanation.

  • Error number invalid when using case when

    I have a table called NATIONAL_RARE_ECOSYSTEMS that contains 1 column called TEST_COLUMN (data type: varchar2):

    TEST_COLUMN
    rare ecosystem
    rare
    0
    0
    (null)
    (null)

    what I want is a query that will add a column called NRE_SCORE that will give each instance of line a score of 0 if it is null.
    If it is 0, then the score should be 0.
    If the line contains any text, partition should be 1

    I wrote the request:

    SELECT
    (CASE WHEN test_column is null THEN 0)
    WHEN test_column = 0 THEN 0
    WHEN test_column > 0, 1
    END) AS NRE_SCORE
    OF NATIONAL_RARE_ECOSYSTEMS;

    I get the error message:

    ORA-01722: invalid number
    01722 00000 - "invalid number."

    I think it is because on the 2nd and 3rd line, trying to perform arithmetic operations on a column which is varchar2 which I know that I can't do.

    How can I write a query that says: If the line contains text, then gives the score of 1?

    I'm using oracle 11g.

    Hello

    993451 wrote:
    I have a table called NATIONAL_RARE_ECOSYSTEMS that contains 1 column called TEST_COLUMN (data type: varchar2):

    TEST_COLUMN
    rare ecosystem
    rare
    0
    0
    (null)
    (null)

    what I want is a query that will add a column called NRE_SCORE that will give each instance of line a score of 0 if it is null.
    If it is 0, then the score should be 0.
    If the line contains any text, partition should be 1

    Any text other than '0', you mean. I guess that doesn't matter if this text is all the numbers, like '9876 'or something with no numbers, as 'rare'.

    I wrote the request:

    SELECT
    (CASE WHEN test_column is null THEN 0)
    WHEN test_column = 0 THEN 0
    WHEN test_column > 0 THEN 1
    END) AS NRE_SCORE
    OF NATIONAL_RARE_ECOSYSTEMS;

    I get the error message:

    ORA-01722: invalid number
    01722 00000 - "invalid number."

    I think it is because on the 2nd and 3rd line, trying to perform arithmetic operations on a column which is varchar2 which I know that I can't do.

    You are not actually doing arithmetic, but you compare your VARCHAR2 column, so he tries to convert the string to a NUMBER, and that's why you get the error ORA-01722.
    >

    How can I write a query that says: If the line contains text, then gives the score of 1?

    I'm using oracle 11g.

    Here's one way:

    SELECT       CASE
               WHEN  NVL (test_column, '0') = '0'
               THEN  0
               ELSE  1
           END          AS nre_score
    ,       ...          -- you must want other columns, too
    FROM       national_rare_ecosystems
    ;
    

    Since you are not really care on the numerical value, do not use numbers anywhere; stick with VARCHAR2s, for example '0'.

    I hope that answers your question.
    If not, post a small example data (CREATE TABLE and only relevant columns, INSERT statements) and also publish outcomes from these data.
    Point where the above query was to get erroneous results, and explain, using specific examples, how you get these results of the sample data in these palces.
    See the FAQ forum {message identifier: = 9360002}

  • Help with CASE

    Hello people.

    FIELDS IN TABLE OF PHONE CALLS: EMP_ID, TELNO, COST, TYPE

    TYPE can be GIVEN or VOICE

    1 EMP_ID has more than 1 TELNO

    I need a report with the following columns:

    EMP_ID, TELNO, VOICE_COST, DATA_COST


    I need something like:
    SELECT EMP_ID , TELNO, SUM(COST),
    SUM(CASE COST WHEN TYPE = DATE THEN ...... END) AS VOICE, 
    SUM(CASE COST WHEN TYPE = VOICE ...... END) AS DATA
    FROM PHONECALLS
    GROUP BY EMP_ID, TELNO
    ORDER BY EMP_ID ASC;
    Thank you in advance.

    Something like that?

    SELECT EMP_ID , TELNO, SUM(COST),
    SUM(CASE TYPE WHEN 'DATE' THEN COST END) AS VOICE,
    SUM(CASE TYPE WHEN 'VOICE' THEN COST END) AS DATA
    FROM PHONECALLS
    GROUP BY EMP_ID, TELNO
    ORDER BY EMP_ID ASC;
    

    Or the alternative way of use CASES:

    SELECT EMP_ID , TELNO, SUM(COST),
    SUM(CASE WHEN TYPE = 'DATE' THEN COST END) AS VOICE,
    SUM(CASE WHEN TYPE = 'VOICE' THEN COST END) AS DATA
    FROM PHONECALLS
    GROUP BY EMP_ID, TELNO
    ORDER BY EMP_ID ASC;
    

    The first use of the CASE is simple - the other can have as expressions complex enough ;-)

  • bad result of 10g using sys_connect_by_path, COUNT (*) OVER (PARTITION OF...)

    Hello

    I get incorrect results when I run my SQL on Oracle 10.2.0.4 prod database.
    When I run the same SQL on Oracle 11.2.0.1 prod database, I get the results I expect.

    See the PATH_TO_EMP_ROOT column in 10g (all are null, why?)

    Here's the SQLs and respective results on Oracle 10.2.0.4 prod database:
    create table TEST_WITH_EMP_TABLE
    (
      EMP_ID NUMBER(5) NOT NULL,
      EMP_NAME VARCHAR2(100) NOT NULL,
      MGR_EMP_ID NUMBER(5),
      CONSTRAINT TEST_WITH_EMP_TABLE_PK
          PRIMARY KEY (EMP_ID) USING INDEX,
       CONSTRAINT TEST_WITH_EMP_TABLE_FK1
          FOREIGN KEY (MGR_EMP_ID)
          REFERENCES TEST_WITH_EMP_TABLE(EMP_ID) ON DELETE CASCADE
    );
    
    INSERT INTO TEST_WITH_EMP_TABLE  VALUES (10, 'Emp1', null);
    INSERT INTO TEST_WITH_EMP_TABLE  VALUES (20, 'Emp2', 10);
    INSERT INTO TEST_WITH_EMP_TABLE  VALUES (30, 'Emp3', 20);
    INSERT INTO TEST_WITH_EMP_TABLE  VALUES (40, 'Emp4', 30);
    INSERT INTO TEST_WITH_EMP_TABLE  VALUES (50, 'Emp5', 10);
    INSERT INTO TEST_WITH_EMP_TABLE  VALUES (60, 'Emp6', 50);
    INSERT INTO TEST_WITH_EMP_TABLE  VALUES (70, 'Emp7', 10);
    INSERT INTO TEST_WITH_EMP_TABLE  VALUES (80, 'Emp8', null);
    commit;
    
    select level as EMP_LEVEL, 
           sys_connect_by_path(EMP_ID, '/') as PATH_TO_EMP_ROOT, 
           COUNT(*) OVER (PARTITION BY level, MGR_EMP_ID) as EMPS_COUNT,
           EMP_ID, EMP_NAME, MGR_EMP_ID
    from TEST_WITH_EMP_TABLE
    START WITH MGR_EMP_ID IS NULL
    CONNECT BY NOCYCLE PRIOR  EMP_ID = MGR_EMP_ID
    ORDER BY EMP_LEVEL, MGR_EMP_ID;
    
    EMP_LEVEL   PATH_TO_EMP_ROOT    EMPS_COUNT  EMP_ID  EMP_NAME    MGR_EMP_ID
    ---------   ----------------    ----------  ------  --------    -----------
    1           (null)              2           10      Emp1        (null)
    1           (null)              2           80      Emp8        (null)
    2           (null)              3           20      Emp2        10
    2           (null)              3           50      Emp5        10
    2           (null)              3           70      Emp7        10
    3           (null)              1           30      Emp3        20
    3           (null)              1           60      Emp6        50
    4           (null)              1           40      Emp4        30
    Exact same SQL running on * 11.2.0.1 Oracle database * as a result of results (than I expected on 10.2 as well):
    EMP_LEVEL   PATH_TO_EMP_ROOT    EMPS_COUNT  EMP_ID  EMP_NAME    MGR_EMP_ID
    ---------   ----------------    ----------  ------  --------    -----------
    1           /10                 2           10      Emp1        (null)
    1           /80                 2           80      Emp8        (null)
    2           /10/20              3           20      Emp2        10
    2           /10/50              3           50      Emp5        10
    2           /10/70              3           70      Emp7        10
    3           /10/20/30           1           30      Emp3        20
    3           /10/50/60           1           60      Emp6        50
    4           /10/20/30/40        1           40      Emp4        30
    Y at - it a bug known RDBMS? Any change that I can do to get this working on 10.2, SQL database as well?

    The other strange thing is that if I remove the
    COUNT(*) OVER (PARTITION BY level, MGR_EMP_ID) as EMPS_COUNT
    the select part of SQL on 10.2.0.4 DB column, the
     PATH_TO_EMP_ROOT 
    I get now is correct even on the 10.2 database.

    Kind regards
    Vivek.
    select level as EMP_LEVEL,
           sys_connect_by_path(emp_id, '/') as path_to_emp_root,
           --COUNT(*) OVER (PARTITION BY MGR_EMP_ID) as EMPS_COUNT,
           EMPS_COUNT,
           emp_id, emp_name, mgr_emp_id
    from (select emp_id, emp_name, mgr_emp_id,
          count(*) over (partition by mgr_emp_id) as emps_count
          from TEST_WITH_EMP_TABLE)
    start with mgr_emp_id is null
    connect by nocycle prior   emp_id=mgr_emp_id
    ORDER BY EMP_LEVEL, MGR_EMP_ID;
    

Maybe you are looking for

  • UJ-840 CDROM in a Qosmio F20 years does not correctly read the media

    Hi people,I m getting desperate now! Have a dissitation I need to access with a cdrom (UJ - 840 years) on a Qosmio F20 running Windows Vista Ultimate.A message says that it is not connected, even if it will read CDs. Can someone help please. When I i

  • EliteBook 8540w: RJ-11 Port

    Hey, can I connect internet without the router via the RJ-11 port... Tell me how to set up he...

  • Control data DATAKOM DKM 409 RS485 modbus output

    Hello world My project is to control a furnace and im using DATAKOM DKM 409 with rs485 modbus output. in this project, I want to monitor data using labview.  reason to do this, I use a RS 485 to RS 232 converter but when I connect them to each other

  • Which is faster a bit manipulation to the table or image using the vision

    I have to perform an operation on an image.  It involves the calculation of the new locations for the pixels for each pixel of the image.  Which is the fastest way to do it.  Manipulate the pixels as elements of the array for loops, or manipulate the

  • Hello from blackBerry Smartphones

    Hello, in spite of having a "BOLD" for a year now I'm new here. Recently changed handset that the original stopped battery charge. And now I have problems of vaious with applications. (1) can't download windows live messenger. simply no button to do.