FIRST_VALUE & LAST_VALUE

Given the following sample data:
AverageRate CurrencyDate
1.0001            2001-09-03
1.0001            2001-09-04
1.0002            2001-09-05
1.0002            2001-09-06
1.0005            2001-09-07
1.0005            2001-09-08
1.0005            2001-09-09
1.0001            2001-09-10
1.0002            2001-09-11
1.0002            2001-09-12
How can I, using FIRST_VALUE and LAST_VALUE, return the desired output:
AverageRate From            To
1.0001            2001-09-03   2001-09-04
1.0002            2001-09-05   2001-09-06
1.0005            2001-09-07   2001-09-09
1.0001            2001-09-10   2001-09-10
1.0002            2001-09-11   2001-09-12
I know how to do this using min/max, self joins and row_number() with partition by, but surely with 2012 there is a simpler (and more optimized) solution which only requires one select statement.  Are my expectations too much?

First_Value, Lag, Lead, ROWS, and RANGE are great additions (Oracle still has more cool analytic functions than SQL server though), but they won't necessarily magically solve all problems.  If your data didn't have the unusual position related duplicates
(where 1.0002 showed up again later in the list, but is a different group to the first time through), your query might have fit 100 percent nicely into a less complex First_Value scenario.
Here's a way that takes care of it, that does use new SQL 2012 feature ROWS and also FIRST_VALUE.  The key element is the "ROWS" clause, where we were able to limit the window to rows that occurred BEFORE the current row.  Then FIRST_VALUE
at the final select statement too.
Create_Testdata:
Declare @Tbl table (avgrate decimal(9,4), currdate date)
Insert @Tbl Select 1.0001, '2001-09-03'
Insert @Tbl Select 1.0001, '2001-09-04'
Insert @Tbl Select 1.0002, '2001-09-05'
Insert @Tbl Select 1.0002, '2001-09-06'
Insert @Tbl Select 1.0005, '2001-09-07'
Insert @Tbl Select 1.0005, '2001-09-08'
Insert @Tbl Select 1.0005, '2001-09-09'
Insert @Tbl Select 1.0001, '2001-09-10'
Insert @Tbl Select 1.0002, '2001-09-11'
Insert @Tbl Select 1.0002, '2001-09-12'
Lister:
With L1_RowNums_Lead_Lag as
Select *
, row_number() over(order by @@Servername) as RN
, lead(avgrate) over(order by @@servername) as NextRate
, lag(avgrate) over(order by @@servername) as PrevRate
From @Tbl
, L2_RowFamily as
Select *
, case When (Prevrate <> avgrate and NextRate <> Avgrate) then RN
when NextRate = AvgRate and IsNull(PrevRate, -1) <> AvgRate then RN
Else NULL
End as RowFamily
From L1_RowNums_Lead_Lag
, L3_RowFamily_Assign as
Select *
, case when RowFamily is Null
Then Max(RowFamily) over(partition by avgrate order by rn Rows between unbounded preceding and current row)
Else RowFamily
End as RowFamily_All
from L2_RowFamily
, L4_Final as
Select *
, first_Value(Currdate) over(partition by RowFamily_all order by RowFamily_all) as FirstCurrdate
, Last_Value(Currdate) over(partition by RowFamily_all order by RowFamily_all) as LastCurrdate
From L3_RowFamily_Assign
Select * from L4_Final /* Where clause has to be in final query */
where RowFamily is not null
order by RN;
Results match your posted desired results.

Similar Messages

  • FIRST_VALUE,LAST_VALUE,invalid_identifier

    Hello,
    I am converting the ACCESS scripts to ORACLE sql. There is FIRST function in Access script. I converted in oracle sql language, but oracle gives an error as "invalid identifier" that I can not understand the reason.
    If you will help to solve this problem, I am really really appreciate.
    Access query:
    select
    First([Reporting Comps].COMPCODE) AS Cage,
    Last(IIf([Reporting Comps]![COMPCODE] Is Not Null,[Reporting Comps]![compcode],"")) AS MFR,
    First(COMPANIES.COMPANY_NAME) AS FirstOfCOMPANY_NAME,
    First(COMPANIES.COMPANY_CODE) AS FirstOfCOMPANY_CODE,
    Last(IIf([Reporting Comps_1]![COMPCODE] Is Not Null,[Reporting Comps_1]![compcode],"")) AS 2MFR,
    First(COMPANIES_2.COMPANY_NAME) AS FirstOfCOMPANY_NAME1,
    First([Reporting Comps_2].COMPCODE) AS 3MFR,
    IIf([MFR] Is Not Null,[MFR],IIf([3MFR] Is Not Null,[3MFR],IIf([2MFR] Is Not Null,[2MFR],"Others"))) AS M
    My script for oracle:
    SELECT X,Y,Z,
    FIRST_VALUE(BI_Reporting_Comps.COMPCODE) OVER ( ORDER BY IND_AUTO_KEY ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) CAGE,
    LAST_VALUE(CASE WHEN BI_REPORTING_COMPS.COMPCODE IS NOT NULL THEN BI_REPORTING_COMPS.COMPCODE ELSE NULL END) OVER ( ORDER BY IND_AUTO_KEY ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) MFR,
    FIRST_VALUE(COMPANIES.COMPANY_NAME) OVER ( ORDER BY IND_AUTO_KEY ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FirstOfCOMPANY_NAME,
    FIRST_VALUE(COMPANIES.COMPANY_CODE) OVER ( ORDER BY IND_AUTO_KEY ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FirstOfCOMPANY_CODE,
    LAST_VALUE(CASE WHEN BI_REPORTING_COMPS.COMPCODE IS NOT NULL THEN BI_REPORTING_COMPS.COMPCODE ELSE NULL END) OVER ( ORDER BY IND_AUTO_KEY ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) MFR2,
    FIRST_VALUE(COMPANIES.COMPANY_NAME) OVER ( ORDER BY IND_AUTO_KEY ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FirstOfCOMPANY_NAME1,
    CASE WHEN MFR Is Not Null THEN MFR
    WHEN MFR2 Is Not Null THEN MFR2
    WHEN MF3 Is Not Null THEN MFR3
    ELSE 'OTHERS'
    END AS MANUFACTURER
    FROM .............
    GROUP BY
    X,
    Y,
    Z,
    CASE WHEN MFR Is Not Null THEN MFR
    WHEN MFR2 Is Not Null THEN MFR2
    WHEN MF3 Is Not Null THEN MFR3
    ELSE 'OTHERS'
    END
    ORDER BY IND_AUTO_KEY ASC;

    Hello
    I've reformatted your code to make it more readable. When you post code please remember to use the {noformat}{noformat} tag before and after to ensure the formatting is preserved.SELECT BI_INVOICES.REPORTED_IN,
    BI_Invoices.IND_AUTO_KEY,
    BI_Invoices.Invoice,
    BI_Invoices.Customer,
    BI_Invoices."P/N",
    BI_Invoices.Qty_Ship,
    BI_Invoices.Unit_Cost,
    BI_Invoices.Unit_Sell,
    BI_Invoices.Total_Cost,
    BI_Invoices.Total_Sales,
    CASE
    WHEN BI_INVOICES.END_DEST1 '@'--<MISSING OPERATOR
    THEN BI_INVOICES.END_DEST1
    WHEN BI_INV_DEST_REF_1.DEST IS NOT NULL THEN BI_INV_DEST_REF_1.DEST
    ELSE bi_inv_dest_ref_2.destination
    END
    AS End_Dest,
    BI_Invoices.End_App,
    BI_Invoices.Salesperson,
    BI_Invoices.SOD_AUTO_KEY,
    FIRST_VALUE (
    BI_Reporting_Comps.COMPCODE)
    OVER (ORDER BY BI_INVOICES.IND_AUTO_KEY
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
    Cage,
    LAST_VALUE (
    CASE
    WHEN BI_REPORTING_COMPS.COMPCODE IS NOT NULL
    THEN
    BI_REPORTING_COMPS.COMPCODE
    ELSE
    END)
    OVER (ORDER BY BI_INVOICES.IND_AUTO_KEY
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
    MFR1,
    FIRST_VALUE (
    COMPANIES.COMPANY_NAME)
    OVER (ORDER BY BI_INVOICES.IND_AUTO_KEY
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
    FirstOfCOMPANY_NAME,
    LAST_VALUE (
    CASE
    WHEN BI_REPORTING_COMPS.COMPCODE IS NOT NULL
    THEN
    BI_REPORTING_COMPS.COMPCODE
    ELSE
    END)
    OVER (ORDER BY BI_INVOICES.IND_AUTO_KEY
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
    MFR2,
    FIRST_VALUE (
    COMPANIES.COMPANY_NAME)
    OVER (ORDER BY BI_INVOICES.IND_AUTO_KEY
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
    FirstOfCOMPANY_NAME1,
    FIRST_VALUE (
    BI_Reporting_Comps.COMPCODE)
    OVER (ORDER BY BI_INVOICES.IND_AUTO_KEY
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
    MFR3
    FROM QCTL.STOCK
    LEFT JOIN QCTL.PO_DETAIL
    ON QCTL.STOCK.POD_AUTO_KEY = QCTL.PO_DETAIL.POD_AUTO_KEY
    LEFT JOIN QCTL.PO_HEADER
    ON QCTL.PO_DETAIL.POH_AUTO_KEY = QCTL.PO_HEADER.POH_AUTO_KEY
    AND QCTL.STOCK.ORIGINAL_PO_NUMBER = QCTL.PO_HEADER.PO_NUMBER
    LEFT JOIN QCTL.RO_DETAIL
    ON QCTL.STOCK.ROD_AUTO_KEY = QCTL.RO_DETAIL.ROD_AUTO_KEY
    LEFT JOIN QCTL.RO_HEADER
    ON QCTL.RO_DETAIL.ROH_AUTO_KEY = QCTL.RO_HEADER.ROH_AUTO_KEY
    LEFT JOIN QCTL.COMPANIES
    ON QCTL.PO_HEADER.CMP_AUTO_KEY = QCTL.COMPANIES.CMP_AUTO_KEY
    AND QCTL.RO_HEADER.CMP_AUTO_KEY = QCTL.COMPANIES.CMP_AUTO_KEY
    LEFT JOIN BI_REPORTING_COMPS
    ON QCTL.COMPANIES.CMP_AUTO_KEY = BI_REPORTING_COMPS.CMP_AUTO_KEY
    RIGHT JOIN QCTL.STOCK_RESERVATIONS
    ON QCTL.STOCK_RESERVATIONS.STM_AUTO_KEY = QCTL.STOCK.STM_AUTO_KEY
    RIGHT JOIN BI_INVOICES
    ON BI_INVOICES.SOD_AUTO_KEY = QCTL.STOCK_RESERVATIONS.SOD_AUTO_KEY
    LEFT JOIN BI_INV_DEST_REF_2
    ON BI_INVOICES.INVOICE = BI_INV_DEST_REF_2.DESTINATION
    LEFT JOIN BI_INV_DEST_REF_1
    ON BI_INVOICES.INVOICE = BI_INV_DEST_REF_1.INVOICE
    GROUP BY BI_INVOICES.REPORTED_IN,
    BI_Invoices.IND_AUTO_KEY,
    BI_Invoices.Invoice,
    BI_Invoices.Customer,
    BI_Invoices."P/N",
    BI_Invoices.Qty_Ship,
    BI_Invoices.Unit_Cost,
    BI_Invoices.Unit_Sell,
    BI_Invoices.Total_Cost,
    BI_Invoices.Total_Sales,
    CASE
    WHEN BI_INVOICES.END_DEST1 '@' --<MISSING OPERATOR
    THEN
    BI_INVOICES.END_DEST1
    WHEN BI_INV_DEST_REF_1.DEST IS NOT NULL
    THEN
    BI_INV_DEST_REF_1.DEST
    ELSE
    bi_inv_dest_ref_2.destination
    END,
    BI_Invoices.End_App,
    BI_Invoices.Salesperson,
    BI_Invoices.SOD_AUTO_KEY,
    BI_Reporting_Comps.COMPCODE,
    COMPANIES.COMPANY_NAME
    I've marked 2 lines with MISSING OPERATOR.  If you were intending for that to be Not Equal, you need to use the != rather than the "<" and ">" operator.  It's a "feature" of the forum software here.
    Also, what's this bit meant to do?LAST_VALUE (
    CASE
    WHEN BI_REPORTING_COMPS.COMPCODE IS NOT NULL
    THEN
    BI_REPORTING_COMPS.COMPCODE
    ELSE
    END
    You're saying if BI_REPORTING_COMPS.COMPCODE is not null  then use it otherwise use null.  In oracle when you assign '' to a string it is actually set to null.  With that in mind, you could just useLAST_VALUE (BI_REPORTING_COMPS.COMPCODE)

  • SAS vs Oracle comparison for statistical modeling

    Hi,
    I am working on a project that require a lot of statistical analysis. as we are in a preliminary phase of determining which way to go, someone recommended to use SAS.
    would you be able to share your experience/comments related to SAS vs Oracle comparison when it comes down to using statistical models within each of these applications. and is there a list of all statistical models that Oracle offers (it could be handy to compare it with our requirements.)
    Plus, would also like to know if there is a way to test these models... just like APEX is offered free for testing purposes @ apex.oracle.com
    Thanks in advance

    You don't go into much detail regarding what types of statistical technques that you might want to use. First, Oracle both partners with SAS and competes and SAS. In terms of Oracle technology for statistics and models, we ship about 50 basic statistical technques with EVERY Oracle Database for free. Those stats include below. See SQL Reference Guide for details:
    Descriptive Statistics
    DBMS_STAT_FUNCS: summarizes numerical columns of a table and returns count, min, max, range, mean, median, stats_mode, variance, standard deviation, quantile values, +/- n sigma values, top/bottom 5 values
    Correlations
    Pearson’s correlation coefficients, Spearman's and Kendall's (both nonparametric).
    Cross Tabs
    Enhanced with % statistics: chi squared, phi coefficient, Cramer's V, contingency coefficient, Cohen's kappa
    Hypothesis Testing
    Student t-test , F-test, Binomial test, Wilcoxon Signed Ranks test, Chi-square, Mann Whitney test, Kolmogorov-Smirnov test, One-way ANOVA
    Distribution Fitting
    Ranking functions
    rank, dense_rank, cume_dist, percent_rank, ntile
    Window Aggregate functions (moving & cumulative)
    Avg, sum, min, max, count, variance, stddev, first_value, last_value
    LAG/LEAD functions
    Direct inter-row reference using offsets
    Reporting Aggregate functions
    Sum, avg, min, max, variance, stddev, count, ratio_to_report
    Statistical Aggregates
    Correlation, linear regression family, covariance
    Linear regression
    Fitting of an ordinary-least-squares regression line to a set of number pairs.
    Frequently combined with the COVAR_POP, COVAR_SAMP, and CORR functions
    Kolmogorov-Smirnov Test, Anderson-Darling Test, Chi-Squared Test, Normal, Uniform, Weibull, Exponential
    Additionally, Oracle has a Database Option called Oracle Advanced Analytics which delivers 12+ hi-performance, data mining algorithms (e.g. clustering, decision trees, regression, association rules, anomaly detection, text mining, etc.) as native SQL functions that can be called from SQL, the R language or the Oracle Data Miner workflow GUI (ships with SQL Developer). There is a LOT more information on the OAA Option here http://www.oracle.com/technetwork/database/options/advanced-analytics/index.html?ssSourceSiteId=ocomen.
    Hope this helps. cb

  • Average YTD in SSRS

    The image above is a replica of a report that already exist. Now users want to see average Year to Day(YTD) per for each product. The idea is to aggregate the sum of each product and divide by the count of months. This report is group by month by year.
    I understand using Window Function but I am running Sql Server 2008 so cannot frame. How do I go about this using SSRS?
    Zionlite

    Hi Zionlite,
    Could you provide some sample data in form of a CREATE temporary table or CTE declaration?
    Your example looks odd to me, als YTD Sum does not align with MTD Sums. Maybe you are calculating on a fiscal year and calculation does not start with january....but even then it's odd to me that YTD Sales Tables is 50 in January, 100 (not 50+10 = 60)
    in February and dops back to 50 in March ?!
    Regarding alternatives to framing via Window Functions Itzik Ben Gan suggests two alternativ methods in his book "Microsoft SQL Server 2012 HIgh-Performance T-SQL USing Window Functions".
    Here an excerpt of the code provided by him. Maybe that helps already.
    -- FIRST_VALUE, LAST_VALUE, NTH_VALUE
    -- FIRST_VALUE, LAST_VALUE as window functions
    SELECT custid, orderdate, orderid, val,
    FIRST_VALUE(val) OVER(PARTITION BY custid
    ORDER BY orderdate, orderid) AS val_firstorder,
    LAST_VALUE(val) OVER(PARTITION BY custid
    ORDER BY orderdate, orderid
    ROWS BETWEEN CURRENT ROW
    AND UNBOUNDED FOLLOWING) AS val_lastorder
    FROM Sales.OrderValues;
    custid orderdate orderid val val_firstorder val_lastorder
    1 2007-08-25 10643 814.50 814.50 933.50
    1 2007-10-03 10692 878.00 814.50 933.50
    1 2007-10-13 10702 330.00 814.50 933.50
    1 2008-01-15 10835 845.80 814.50 933.50
    1 2008-03-16 10952 471.20 814.50 933.50
    1 2008-04-09 11011 933.50 814.50 933.50
    2 2006-09-18 10308 88.80 88.80 514.40
    2 2007-08-08 10625 479.75 88.80 514.40
    2 2007-11-28 10759 320.00 88.80 514.40
    2 2008-03-04 10926 514.40 88.80 514.40
    3 2006-11-27 10365 403.20 403.20 660.00
    3 2007-04-15 10507 749.06 403.20 660.00
    3 2007-05-13 10535 1940.85 403.20 660.00
    3 2007-06-19 10573 2082.00 403.20 660.00
    3 2007-09-22 10677 813.37 403.20 660.00
    3 2007-09-25 10682 375.50 403.20 660.00
    3 2008-01-28 10856 660.00 403.20 660.00
    -- returning one row per customer
    WITH C AS
    SELECT custid,
    FIRST_VALUE(val) OVER(PARTITION BY custid
    ORDER BY orderdate, orderid) AS val_firstorder,
    LAST_VALUE(val) OVER(PARTITION BY custid
    ORDER BY orderdate, orderid
    ROWS BETWEEN CURRENT ROW
    AND UNBOUNDED FOLLOWING) AS val_lastorder,
    ROW_NUMBER() OVER(PARTITION BY custid ORDER BY (SELECT NULL)) AS rownum
    FROM Sales.OrderValues
    SELECT custid, val_firstorder, val_lastorder
    FROM C
    WHERE rownum = 1;
    custid val_firstorder val_lastorder
    1 814.50 933.50
    2 88.80 514.40
    3 403.20 660.00
    4 480.00 491.50
    5 1488.80 1835.70
    6 149.00 858.00
    7 1176.00 730.00
    8 982.00 224.00
    9 88.50 792.75
    10 1832.80 525.00
    -- pre SQL Server 2012 solutions
    -- Using row numbers
    WITH OrdersRN AS
    SELECT custid, val,
    ROW_NUMBER() OVER(PARTITION BY custid
    ORDER BY orderdate, orderid) AS rna,
    ROW_NUMBER() OVER(PARTITION BY custid
    ORDER BY orderdate DESC, orderid DESC) AS rnd
    FROM Sales.OrderValues
    SELECT custid,
    MAX(CASE WHEN rna = 1 THEN val END) AS firstorderval,
    MAX(CASE WHEN rnd = 1 THEN val END) AS lastorderval,
    MAX(CASE WHEN rna = 3 THEN val END) AS thirdorderval
    FROM OrdersRN
    GROUP BY custid;
    custid firstorderval lastorderval thirdorderval
    1 814.50 933.50 330.00
    2 88.80 514.40 320.00
    3 403.20 660.00 1940.85
    4 480.00 491.50 407.70
    5 1488.80 1835.70 2222.40
    6 149.00 858.00 330.00
    7 1176.00 730.00 7390.20
    8 982.00 224.00 224.00
    9 88.50 792.75 1549.60
    10 1832.80 525.00 966.80
    -- using carry-along-sort technique
    -- step 1: create concatenated strings
    SELECT custid,
    CONVERT(CHAR(8), orderdate, 112)
    + STR(orderid, 10)
    + STR(val, 14, 2)
    COLLATE Latin1_General_BIN2 AS s
    FROM Sales.OrderValues;
    custid s
    85 20060704 10248 440.00
    79 20060705 10249 1863.40
    34 20060708 10250 1552.60
    84 20060708 10251 654.06
    76 20060709 10252 3597.90
    34 20060710 10253 1444.80
    14 20060711 10254 556.62
    68 20060712 10255 2490.50
    88 20060715 10256 517.80
    35 20060716 10257 1119.90
    -- step 2: group, aggregate and extract
    WITH C AS
    SELECT custid,
    CONVERT(CHAR(8), orderdate, 112)
    + STR(orderid, 10)
    + STR(val, 14, 2)
    COLLATE Latin1_General_BIN2 AS s
    FROM Sales.OrderValues
    SELECT custid,
    CAST(SUBSTRING(MIN(s), 19, 14) AS NUMERIC(12, 2)) AS firstorderval,
    CAST(SUBSTRING(MAX(s), 19, 14) AS NUMERIC(12, 2)) AS lastorderval
    FROM C
    GROUP BY custid;
    custid firstorderval lastorderval
    1 814.50 933.50
    2 88.80 514.40
    3 403.20 660.00
    4 480.00 491.50
    5 1488.80 1835.70
    6 149.00 858.00
    7 1176.00 730.00
    8 982.00 224.00
    9 88.50 792.75
    10 1832.80 525.00
    -- in case ordering element supports negative values, e.g., orderid
    WITH C AS
    SELECT custid,
    CONVERT(CHAR(8), orderdate, 112)
    + CASE SIGN(orderid) WHEN -1 THEN '0' ELSE '1' END -- negative sorts before nonnegative
    + STR(CASE SIGN(orderid)
    WHEN -1 THEN 2147483648 -- if negative add abs(minnegative)
    ELSE 0
    END + orderid, 10)
    + STR(val, 14, 2)
    COLLATE Latin1_General_BIN2 AS s
    FROM Sales.OrderValues
    SELECT custid,
    CAST(SUBSTRING(MIN(s), 20, 14) AS NUMERIC(12, 2)) AS firstorderval,
    CAST(SUBSTRING(MAX(s), 20, 14) AS NUMERIC(12, 2)) AS lastorderval
    FROM C
    GROUP BY custid;
    Cheers
    Martin

  • First/Last in a group by

    Hi !
    I have a table with session_ids, url a user visited and the time the did it.
    I need output pr. session_id
    Session id, durtaion of the session, the first page he visted, the last page he visited
    I have tried a lot with first_value, last_value, first/last in various analytic functions, but my head cant seem to find the correct solution.
    (aprt from coding it in PL/SQL)
    This is an example of my table:
    drop table mette_interval;
    create table mette_interval (session_i number, url varchar2(400), url_time date);
    insert into mette_interval values (1, 'start page', sysdate);
    insert into mette_interval values (1, 'xxxxside z', sysdate+interval '5' second);
    insert into mette_interval values (1, 'end pagexxxxxside z', sysdate+interval '6' second);
    insert into mette_interval values (2, 'page xxx z',sysdate+interval '0' second);
    insert into mette_interval values (2, 'page yyyy z', sysdate+interval '10' second);
    insert into mette_interval values (3, 'page whatever z', sysdate+interval '1' second);
    select session_i, (max(url_time)-min(url_time))*24*60*60 duration
    from mette_interval
    group by session_i;
    Can you give me a hint?
    Regards
    Mette

    SQL> select * from mette_interval;
    SESSION_I URL                  URL_TIME
             1 start page           24-MAR-09
             1 xxxxside z           24-MAR-09
             1 end pagexxxxxside z  24-MAR-09
             2 page xxx z           24-MAR-09
             2 page yyyy z          24-MAR-09
             3 page whatever z      24-MAR-09
    6 rows selected.
    SQL> select session_i,(max(url_time)-min(url_time))*24*60*60 duration,
      2        max(url) keep(dense_rank first order by url_time) frst,
      3        max(url) keep(dense_rank last order by url_time) lst
      4   from mette_interval
      5   group by session_i;
    SESSION_I   DURATION FRST                 LST
             1          6 start page           end pagexxxxxside z
             2         10 page xxx z           page yyyy z
             3          0 page whatever z      page whatever zToo Late...
    Edited by: jeneesh on Mar 24, 2009 12:38 PM

  • Replacing Oracle's FIRST_VALUE and LAST_VALUE analytical functions.

    Hi,
    I am using OBI 10.1.3.2.1 where, I guess, EVALUATE is not available. I would like to know alternatives, esp. to replace Oracle's FIRST_VALUE and LAST_VALUE analytical functions.
    I want to track some changes. For example, there are four methods of travel - Air, Train, Road and Sea. Would like to know traveler's first method of traveling and the last method of traveling in an year. If both of them match then a certain action is taken. If they do not match, then another action is taken.
    I tried as under.
    1. Get Sequence ID for each travel within an year per traveler as Sequence_Id.
    2. Get the Lowest Sequence ID (which should be 1) for travels within an year per traveler as Sequence_LId.
    3. Get the Highest Sequence ID (which could be 1 or greater than 1) for travels within an year per traveler as Sequence_HId.
    4. If Sequence ID = Lowest Sequence ID then display the method of travel as First Method of Travel.
    5. If Sequence ID = Highest Sequence ID then display the method of travel as Latest Method of Travel.
    6. If First Method of Travel = Latest Method of Travel then display Yes/No as Match.
    The issue is cells could be blank in First Method of Travel and Last Method of Travel unless the traveler traveled only once in an year.
    Using Oracle's FIRST_VALUE and LAST_VALUE analytical functions, I can get a result like
    Traveler | Card Issue Date | Journey Date | Method | First Method of Travel | Last Method of Travel | Match?
    ABC | 01/01/2000 | 04/04/2000 | Road | Road | Air | No
    ABC | 01/01/2000 | 15/12/2000 | Air | Road | Air | No
    XYZ | 01/01/2000 | 04/05/2000 | Train | Train | Train | Yes
    XYZ | 01/01/2000 | 04/11/2000 | Train | Train | Train | Yes
    Using OBI Answers, I am getting something like this.
    Traveler | Card Issue Date | Journey Date | Method | First Method of Travel | Last Method of Travel | Match?
    ABC | 01/01/2000 | 04/04/2000 | Road | Road | <BLANK> | No
    ABC | 01/01/2000 | 15/12/2000 | Air | <BLANK> | Air | No
    XYZ | 01/01/2000 | 04/05/2000 | Train | Train | <BLANK> | No
    XYZ | 01/01/2000 | 04/11/2000 | Train | <BLANK> | Train | No
    Above, for XYZ traveler the Match? clearly shows a wrong result (although somehow it's correct for traveler ABC).
    Would appreciate if someone can guide me how to resolve the issue.
    Many thanks,
    Manoj.
    Edited by: mandix on 27-Nov-2009 08:43
    Edited by: mandix on 27-Nov-2009 08:47

    Hi,
    Just to recap, in OBI 10.1.3.2.1, I am trying to find an alternative way to FIRST_VALUE and LAST_VALUE analytical functions used in Oracle. Somehow, I feel it's achievable. I would like to know answers to the following questions.
    1. Is there any way of referring to a cell value and displaying it in other cells for a reference value?
    For example, can I display the First Method of Travel for traveler 'ABC' and 'XYZ' for all the rows returned in the same column, respectively?
    2. I tried RMIN, RMAX functions in the RDP but it does not accept "BY" clause (for example, RMIN(Transaction_Id BY Traveler) to define Lowest Sequence Id per traveler). Am I doing something wrong here? Why can a formula with "BY" clause be defined in Answers but not the RPD? The idea is to use this in Answers. This is in relation to my first question.
    Could someone please let me know?
    I understand that this thread that I have posted is related to something that can be done outside OBI, but still would like to know.
    If anything is not clear please let me know.
    Thanks,
    Manoj.

  • Use of FIRST_VALUE OVER in a PL/SQL query

    Hello,
    Here is my problem:
    I'm trying to execute a query using FIRST_VALUE OVER in a PL/SQL procedure, e.g.
    SELECT FIRST_VALUE (name) OVER (order by birthdate)
    FROM birthday_table
    WHERE location = 'HOME';
    I need to get the value returned. I tried to do it using an INTO clause and
    also with EXECUTE IMMEDIATE, but I get an error like "invalid column name".
    Thank you,
    Olivier.

    Assuming the query runs successfully outside of PL/SQL, the execute immediate construct would be:
    execute immediate 'select first_value ... where location = :loc' into v_some_variable using 'HOME';

  • How to get LAST_VALUE from an Analytic Function within a report?

    My analytical report has following sql:
    SELECT....
    DENSE_RANK() OVER (PARTITION BY pco.appropriation ORDER BY pco.appropriation,
    pco.fiscal_year ASC NULLS LAST) "Duration Years",
    SUM(pco.quantity) OVER (PARTITION BY sms.data_source ORDER BY
    sms.data_source, cst.display_nm RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT
    ROW) "Quantity Cum",
    FROM ........
    I have a request to calculate the percentage value by dividing MAX or LASTVALUE of these two functions at current row level:_
    %DENSE_RANK = LAST_VALUE of ? DENSE_RANK() OVER (PARTITION BY pco.appropriation ORDER BY pco.appropriation,
    pco.fiscal_year ASC NULLS LAST) "Duration Years"
    / (divide by)
    DENSE_RANK() OVER (PARTITION BY pco.appropriation ORDER BY pco.appropriation,
    pco.fiscal_year ASC NULLS LAST) "Duration Years"
    %SUM = LAST_VALUE of ? SUM(pco.quantity) OVER (PARTITION BY sms.data_source ORDER BY
    sms.data_source, cst.display_nm RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT
    ROW) "Quantity Cum",
    / (divide by)
    SUM(pco.quantity) OVER (PARTITION BY sms.data_source ORDER BY
    sms.data_source, cst.display_nm RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT
    ROW) "Quantity Cum"
    Example of report output:
    DENSE RANK DENSE RANK % SUM SUM %
    1 10% 10 10%
    2 20% 20 20%
    3 100% 30 100%
    1 10% 10 10%
    2 20% 20 20%
    I appreciate your help to implement LAST_VALUE function for this case. Many thanks in advance.
    Rob.
    Edited by: user10455955 on Dec 17, 2008 9:25 AM

    Hi Rod,
    Thank you for replying. My intentions are:
    1. to get last value of DENSE_RANK(), and divide by fisrt until last DENSE_RANK() value within defined partition.
    Example: I have DENSE_RANK() from 1 to 7, and want to divide last value (7) by 1, 2,... so on until 7, so last value 7 always renders 100%
    2. to get last value of cumulative total, and divide fisrt until and last cumulative total value within defined partition
    Example: I have 3 values 1, 2, 3. Fisrt cumulative total is 1 , second cumulative is 3 (1+2) , third cumulative is 6 (1+2+3). I want to divide last cumulative total 6 by 1, then 2, then 3.
    Thanks again.
    Rob.
    Edited by: user10455955 on Dec 22, 2008 9:16 AM
    Edited by: user10455955 on Dec 22, 2008 9:18 AM

  • Issue with First_value

    Hi,
    I am problem pulling right set of data for the below situation.
    SELECT
    FIRST_VALUE(p1)
    OVER (PARTITION BY workorderid ORDER BY NVL(completeddate,createdate) DESC NULLS LAST) pressure
    FROM HISTORY
    Lets say that result set has values for p1 as no and yes for the same completeddate, then the
    query returns value 'no' because it sorts the data alphabetically.
    all i what is, when the completed date is same for two records then look up create date and give me the value of p1 based on max(create date).
    How do i do that using analytical function?
    Thanks
    Billu

    Sorry, i wasn't clear enough earlier.
    here is my entire query posted :
    SELECT
    m.loannumber,
    w.ordernumber,
    o.spikey clientcode,
    v.id vendorname,
    w.spiworkcode workcode,
    w.department_fk department,
    SUBSTR(w.loantypetermid, 10) loantype,
    TRUNC(w.orderdate) orderdate,
    vw_rhist.wcompleteddate Winterization_Completed_Date,
    CASE WHEN vw_rhist.wintsystemtype = 'HeatingSystemType.Dry'
    THEN 'Dry'
    WHEN vw_rhist.wintsystemtype = 'HeatingSystemType.Steam'
    THEN 'Steam'
    WHEN vw_rhist.wintsystemtype = 'HeatingSystemType.Radiant'
    THEN 'Radiant'
    ELSE NULL
    END System_Type,
    CASE WHEN vw_rhist.pressuretestsystem = 'YesNo.Yes' THEN 'Yes'
    WHEN vw_rhist.pressuretestsystem = 'YesNo.No' THEN 'No'
    ELSE NULL
    END pressuretestsystem,
    CASE WHEN vw_rhist.holdpressure = 'YesNo.Yes' THEN 'Yes'
    WHEN vw_rhist.holdpressure = 'YesNo.No' THEN 'No'
    ELSE NULL
    END holdpressure,
    CASE WHEN vw_rhist.systemwell = 'YesNo.Yes' THEN 'Yes'
    WHEN vw_rhist.systemwell = 'YesNo.No' THEN 'No'
    ELSE NULL
    END systemwell,
    a.state state
    FROM organizationalrole o,
    vendor v,
    serviceableasset s,
    address a,
    mortgage m,
    (SELECT *
    FROM workorder
    WHERE department_fk = 2
    AND loantypetermid IN ( 'LoanType.CDG','LoanType.CV','LoanType.FHA','LoanType.FMC','LoanType.FNM',
    'LoanType.REO','LoanType.UNK','LoanType.VA'))w,
    SELECT workorderid,rnk,wcompleteddate,pressuretestsystem,
    holdpressure,systemwell,wintsystemtype
    FROM
    ((SELECT workorderid,
    RANK() OVER (PARTITION BY workorderid ORDER BY oid) rnk,
    MIN(COALESCE(winterizationdate, completeddate, createdate))
    OVER (PARTITION BY workorderid) wcompleteddate,
    FIRST_VALUE(pressuretestsystem)
    OVER (PARTITION BY workorderid
    ORDER BY NVL(completeddate, createdate) DESC NULLS LAST)
    pressuretestsystem, FIRST_VALUE(holdpressure)
    OVER (PARTITION BY workorderid
    ORDER BY NVL(completeddate, createdate) DESC NULLS LAST)
    holdpressure,
    FIRST_VALUE(systemwell)
    OVER (PARTITION BY workorderid
    ORDER BY NVL(completeddate, createdate) DESC NULLS LAST)
    systemwell,
    FIRST_VALUE(wintsystemtype)
    OVER (PARTITION BY workorderid
    ORDER BY NVL(completeddate, createdate) DESC NULLS LAST)
    wintsystemtype
    FROM vwresulthistory
    WHERE resulttype = 'OrderUpdate'
    AND iswinterized = 'WinterizationCompleted.Yes') vw_rhist1)
    WHERE wCompleteddate >=
    TO_DATE('10/01/2009','MM/DD/YYYY') AND
    wCompleteddate <= TO_DATE('10/6/2009','MM/DD/YYYY')) vw_rhist
    WHERE vw_rhist.rnk = 1
    AND v.objectid = w.vendor_fk
    AND w.ordernumber = vw_rhist.workorderid
    AND w.servicingasset_fk = s.objectid
    AND s.address_fk = a.objectid
    AND o.objectid = w.client_fk
    AND m.objectid = s.primaryloan_fk
    ORDER BY 2
    The problem i have is with the first_value that is in bold. Sometimes I do have two identical completeddate, in that situation, the first_value returns pressuretestsystem sorted aphabetically, say you have two identical completed dates of 12/3/09 and pressuretestsystem values of 'no' and 'yes'. What I get is 'no'.
    In that kind of situations, i want to look up create date and return the latest value (which here is 'yes'). Do i need case statement here?
    Thanks for reading this far.
    Billu.

  • EVALUATE in OBIEE with Analytic function LAST_VALUE

    Hi,
    I'm trying to use EVALUATE with analytic function LAST_VALUE but it is giving me error below:
    [nQSError: 17001] Oracle Error code: 30483, message: ORA-30483: window functions are not allowed here at OCI call OCIStmtExecute. [nQSError: 17010] SQL statement preparation failed. (HY000)
    Thanks
    Kumar.

    Hi Kumar,
    The ORA error tells me that this is something conveyed by the oracle database but not the BI Server. In this case, the BI server might have fired the incorrect query onto the DB and you might want to check what's wrong with it too.
    The LAST_VALUE is an analytic function which works over a set/partition of records. Request you to refer to the semantics at http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions073.htm and see if it is violating any rules here. You may want to post the physical sql here too to check.
    Hope this helps.
    Thank you,
    Dhar

  • First_value in Oracle olap based on non - time dimension

    Hi Experts,
    I am trying to figure out to do first_value kind of calculation in Oracle OLAP.
    Here is the requirement -
    Fact table -
    cust_id valid_flag balance
    1 y 1000
    1 y 1500
    2 N 0
    2 y 2000
    2 y 2500
    If valid_flag ='N' and balance =0, then set balance =0 for other cells for the customer. This needs to be done for all the dimensions.
    Any pointer would be useful.
    Regards, Neelesh

    If the switch is really based on a dimension attribute (named particular_value), then it should be easy to create a derived measure.
    CASE
      WHEN particular_dim.particular_value = 'N'
      THEN 0
      ELSE my_cube.balance
    ENDBut perhaps what you mean is that there is another measure, IS_VALID say, and you need to get the value of IS_VALID for the current cust_id and the member named 'particular_value' of the particular_dim. In this case it would look something like this.
    CASE
      WHEN my_cube.is_valid[particular_dim = 'particular_value'] = 'N'
      THEN 0
      ELSE my_cube.balance
    ENDI expect that neither of the above expressions is right, but it should give you some pointers as to the kinds of tricks you can use.

  • Peformance of First_Value

    Hi ,
    I want to know which of the two queries is better in terms of performance(using first_value or a sub query).
    Let us assume that salary is unique...
    1) select first_value(ename ) over (order by sal) from emp;
    or
    2) select ename from emp where sal = (select min(sal) from emp )
    Thanks,
    Anand

    You are comparing apple with oranges. It is because you are comparing analytical vs aggregate. They are different. Because
    SQL> select first_value(ename ) over (order by sal) from emp;
    FIRST_VALU
    SMITH
    SMITH
    SMITH
    SMITH
    SMITH
    SMITH
    SMITH
    SMITH
    SMITH
    SMITH
    SMITH
    FIRST_VALU
    SMITH
    SMITH
    SMITH
    SMITH
    15 rows selected.
    SQL> select ename from emp where sal = (select min(sal) from emp);
    ENAME
    SMITHFor more information check this url.
    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:74525921631614
    Regards
    Raj

  • LAST_VALUE suggestion

    Hi Guys,
    How to modify LAST_VALUE call in query
    select t.*, last_value( order_val) over(order by order_date) from testx t
    to get 12 for dates 7/1/2010, 8/1/2010, 9/1/2010
    ID     ORDER_DATE     ORDER_VAL     LAST_VALUE(ORDER_VAL)OVER(ORDE
    1     1/1/2010     3     3
    2     2/1/2010     5     5
    3     3/1/2010     7     7
    4     4/1/2010     8     8
    5     5/1/2010     9     9
    6     6/1/2010     12     12
    7     7/1/2010          12
    8     8/1/2010          12
    9     9/1/2010          12
    (Ora 9.2):
    create table testx ( id number, order_date date, order_val number );
    insert into testx values ( 1, to_date('2010-01-01','yyyy-mm-dd'), 3 );
    insert into testx values ( 2, to_date('2010-02-01','yyyy-mm-dd'), 5 );
    insert into testx values ( 3, to_date('2010-03-01','yyyy-mm-dd'), 7 );
    insert into testx values ( 4, to_date('2010-04-01','yyyy-mm-dd'), 8 );
    insert into testx values ( 5, to_date('2010-05-01','yyyy-mm-dd'), 9 );
    insert into testx values ( 6, to_date('2010-06-01','yyyy-mm-dd'), 12 );
    insert into testx values ( 7, to_date('2010-07-01','yyyy-mm-dd'), null );
    insert into testx values ( 8, to_date('2010-08-01','yyyy-mm-dd'), null );
    insert into testx values ( 9, to_date('2010-09-01','yyyy-mm-dd'), null );
    Thanks,
    Regards,
    Piotr

    Thanks for pointing that Alex.
    Not sure if @OP is looking at repeating the Maximum order_value for NULL records or the last value. In case if it hae to be the maximum order_Val, then here it is:
    SQL> ed
    Wrote file afiedt.buf
      1  select id
      2         , order_date
      3         , order_val
      4         , max (order_val) over (partition by grp)
      5      from (
      6    select id
      7         , order_date
      8         , order_val
      9         , sum (nvl2 (order_val, 1, 0)) over (order by order_val) grp
    10*     from testx)
    SQL> /
            ID ORDER_DAT  ORDER_VAL MAX(ORDER_VAL)OVER(PARTITIONBYGRP)
             1 01-JAN-10          3                                  3
             2 01-FEB-10          5                                  5
             3 01-MAR-10          7                                  7
             4 01-APR-10          8                                  8
             6 01-JUN-10         12                                 12
             5 01-MAY-10         15                                 15
             7 01-JUL-10                                            15
             8 01-AUG-10                                            15
             9 01-SEP-10                                            15
    9 rows selected.
    SQL> Edited by: AP on Aug 11, 2010 2:30 AM

  • When to use First instead of  First_Value functions

    When would you use the First_Values function instead of First? What's the difference between the two?

    Here are some examples of both in action. Use the analytic function FIRST_VALUE when you don't want to group your records. Use the aggregate function FIRST when you do.
    select
      deptno ,
      hiredate ,
      ename ,
      first_value( ename ) over ( partition by deptno order by hiredate ) first_hired
    from emp
    order by deptno, hiredate ;
        DEPTNO HIREDATE   ENAME      FIRST_HIRE
            10 1981-06-09 CLARK      CLARK
            10 1981-11-17 KING       CLARK
            10 1982-01-23 MILLER     CLARK
            20 1980-12-17 SMITH      SMITH
            20 1981-04-02 JONES      SMITH
            20 1981-12-03 FORD       SMITH
            20 1987-04-19 SCOTT      SMITH
            20 1987-05-23 ADAMS      SMITH
            30 1981-02-20 ALLEN      ALLEN
            30 1981-02-22 WARD       ALLEN
            30 1981-05-01 BLAKE      ALLEN
            30 1981-09-08 TURNER     ALLEN
            30 1981-09-28 MARTIN     ALLEN
            30 1981-12-03 JAMES      ALLEN
    14 rows selected.
    select
      deptno,
      min(ename) keep ( dense_rank first order by hiredate ) as first_hired
    from emp
    group by deptno
    order by deptno ;
        DEPTNO FIRST_HIRE
            10 CLARK
            20 SMITH
            30 ALLEN
    3 rows selected.As far as analytic FIRST_VALUE versus the analytic version of FIRST, FIRST_VALUE has the option to IGNORE NULLS whereas FIRST doesn't.
    select
      deptno ,
      hiredate ,
      comm ,
      first_value( comm IGNORE NULLS ) over ( partition by deptno order by hiredate desc )
        as first_value ,
      min(comm) keep ( dense_rank first order by hiredate desc )
        over ( partition by deptno )
        as first
    from emp
    order by deptno, hiredate ;
        DEPTNO HIREDATE         COMM FIRST_VALUE      FIRST
            10 1981-06-09
            10 1981-11-17
            10 1982-01-23
            20 1980-12-17
            20 1981-04-02
            20 1981-12-03
            20 1987-04-19
            20 1987-05-23
            30 1981-02-20        300        1400
            30 1981-02-22        500        1400
            30 1981-05-01                   1400
            30 1981-09-08          0        1400
            30 1981-09-28       1400        1400
            30 1981-12-03
    14 rows selected.Other than that the two seem functionally equivalent. I prefer FIRST_VALUE over FIRST though because its syntax is more familiar.
    Joe Fuda
    SQL Snippets
    Message was edited by: SnippetyJoe - added third example

  • First_value

    Can anyone tell me if there is a more efficient way to do the following........
    SELECT distinct accprf.account_id
    first_value(accprf.value_start)
    over (partition by accprf.account_id order by accprf.start_date) ,
    first_value(accprf.value_end)
    over (partition by accprf.account_id order by accprf.end_date desc)
    FROM account_performance accprf
    The table account_performance has more than one row per account_id. Each row has a start date and end date, with account performance information for that time interval. The above gets the values from the very first entry and the very last entry per account_id.
    I was expecting to find a less complicated way to do the above.
    Thanks, Mario.

    Well, in that case it doesn't matter!
    This is a little demonstration:
    SQL> drop table t;
    Table dropped.
    SQL>
    SQL> create table t (c1 number, c2 number, c3 number);
    Table created.
    SQL>
    SQL> insert into t values (1, 1, 10);
    1 row created.
    SQL> insert into t values (1, 2, 11);
    1 row created.
    SQL> insert into t values (1, 3, 7);
    1 row created.
    SQL>
    SQL>
    SQL> insert into t values (2, 3, 20);
    1 row created.
    SQL> insert into t values (2, 4, 21);
    1 row created.
    SQL> insert into t values (2, 5, 15);
    1 row created.
    SQL>
    SQL> SELECT c1,
      2          SUM(c3) keep (dense_rank first order by c2) sum,
      3          MIN(c3) keep (dense_rank first order by c2) min,
      4          MAX(c3) keep (dense_rank first order by c2) max
      5  FROM t
      6  group by c1;
            C1        SUM        MIN        MAX
             1         10         10         10
             2         20         20         20Message was edited by:
    Michel
    Sorry,
    It have made an implicit assumption that c2 was unique or it is not true and then you are right. It must be min and not max to meet the first query.
    Thanks for your correction.

Maybe you are looking for

  • Re-install CS5

    I am facing the same disaster ,,   I am forced to reactivate / reinstall  CS 5  and after 10 hours of trying all options fail .    WHy cant I simply reenter my serial number ,  rather than spead hours on uninstalling then trying to reinstall an 8 hou

  • Webmail Address Book

    I was wondering if their is a way to export or import an address book into webmail (squirrelmail 1.4.5) that is built into 10.4.8. I know that you can add people to your address book through webmail directly and I don't see any options to either impo

  • MIgrating DNS zone

    Hi,  Sorry if this is a really silly question, I just need some clarification. I'm carrying out a project to migrate users/groups and everything else 'AD' from 1 forest into a target forest. There's a 2 way trust in place and I will be starting ADMT

  • Strange Facetime activation error

    I have followed with interest the issues surrounding Facetime activation problems. I have one I have not yet seen. My new IPOD Touch G4 will not activate facetime. I get the most unusual error message: unable to verify email because it is already in

  • No Missed Calls AirPlane Mode Bug

    When I put my iPhone in AirPlane I don't recive calls or iMessages. (Normal) When I disable AirPlane mode, any calls that I recived while AirPlane mode was on don't appear at all. So it shows no missed calls, but Messages do show up. I have tested th