Identifying and grouping consecutive rows in sql

I have following data set:
CREATE TABLE APPS.T1
  ROW_NUM               NUMBER,
  EFFECTIVE_START_DATE  DATE                    NOT NULL,
  EFFECTIVE_END_DATE    DATE                    NOT NULL,
  STATUS                VARCHAR2(30 BYTE)
SET DEFINE OFF;
Insert into APPS.T1
   (ROW_NUM, EFFECTIVE_START_DATE, EFFECTIVE_END_DATE, STATUS)
Values
   (1, TO_DATE('07/01/2009 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('09/06/2009 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'VAC');
Insert into APPS.T1
   (ROW_NUM, EFFECTIVE_START_DATE, EFFECTIVE_END_DATE, STATUS)
Values
   (2, TO_DATE('03/20/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('03/31/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'VAC');
Insert into APPS.T1
   (ROW_NUM, EFFECTIVE_START_DATE, EFFECTIVE_END_DATE, STATUS)
Values
   (3, TO_DATE('08/06/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('08/22/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'VAC');
Insert into APPS.T1
   (ROW_NUM, EFFECTIVE_START_DATE, EFFECTIVE_END_DATE, STATUS)
Values
   (4, TO_DATE('08/23/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('08/26/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'VAC');
Insert into APPS.T1
   (ROW_NUM, EFFECTIVE_START_DATE, EFFECTIVE_END_DATE, STATUS)
Values
   (5, TO_DATE('08/27/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('08/27/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'VAC');
COMMIT;
SELECT * FROM APPS.T1
   ROW_NUM EFFECTIVE EFFECTIVE STATUS                       
         1 01-JUL-09 06-SEP-09 VAC                          
         2 20-MAR-11 31-MAR-11 VAC                          
         3 06-AUG-11 22-AUG-11 VAC                          
         4 23-AUG-11 26-AUG-11 VAC                          
         5 27-AUG-11 27-AUG-11 VAC                          
5 rows selected.My requirement was that row number 3, 4 and 5 be grouped and treated as a single vacation record such that
effective_start_date = 06-AUG-2011 and
effective_end_date = 27-AUG-2011
For this I wrote a query:
SELECT effective_start_date,
       effective_end_date,
       CASE
          WHEN LAG (effective_end_date, 1) OVER (ORDER BY row_num) + 1 = effective_start_date
             THEN 0
          WHEN LEAD (effective_start_date, 1) OVER (ORDER BY row_num) - 1 = effective_end_date
             THEN 0
          ELSE 1
       END row_num
  FROM (SELECT * FROM T1)Now the data returned looks like:
EFFECTIVE EFFECTIVE    ROW_NUM
01-JUL-09 06-SEP-09          1
20-MAR-11 31-MAR-11          1
06-AUG-11 22-AUG-11          0
23-AUG-11 26-AUG-11          0
27-AUG-11 27-AUG-11          0
5 rows selected.Now I can easily use MIN(effective_start_date) and MAX(effective_start_date) group by ROW_NUM to achieve the desired results
SELECT   MIN (effective_start_date) start_dt,
         MAX (effective_start_date) end_dt,
         row_num
    FROM (SELECT effective_start_date,
                 effective_end_date,
                 CASE
                    WHEN LAG (effective_end_date, 1) OVER (ORDER BY row_num) + 1 = effective_start_date
                       THEN 0
                    WHEN LEAD (effective_start_date, 1) OVER (ORDER BY row_num) - 1 = effective_end_date
                       THEN 0
                    ELSE 1
                 END row_num
            FROM (SELECT *
                    FROM t1))
GROUP BY row_num
  HAVING row_num = 0
UNION
SELECT effective_start_date start_dt,
       effective_start_date end_dt,
       row_num
  FROM (SELECT effective_start_date,
               effective_end_date,
               CASE
                  WHEN LAG (effective_end_date, 1) OVER (ORDER BY row_num) + 1 = effective_start_date
                     THEN 0
                  WHEN LEAD (effective_start_date, 1) OVER (ORDER BY row_num) - 1 = effective_end_date
                     THEN 0
                  ELSE 1
               END row_num
          FROM (SELECT *
                  FROM t1))
WHERE row_num = 1
START_DT  END_DT       ROW_NUM
01-JUL-09 01-JUL-09          1
20-MAR-11 20-MAR-11          1
06-AUG-11 27-AUG-11          0
3 rows selected.All done BUT the problem is that there may be several groups of consecutive rows like this. In that case each group should be identified distinctly for GROUP BY clause to work as expected.
I want to assign a unique number to each occurence of such group.
How can I achieve this? Any ideas?
Regards,
Faraz
Edited by: faanwar on May 10, 2012 3:36 PM

Well, actually, you'll need to tweak it a bit. something such as in :Scott@my11g SQL>l
  1  with t (id, dstart, dend, status)
  2  as (
  3       select 1,to_date('01-JUL-09','dd-MON-YY'),to_date('06-SEP-09','dd-MON-YY'),'VAC' from dual
  4       union all select 2,to_date('20-MAR-11','dd-MON-YY'),to_date('31-MAR-11','dd-MON-YY'),'VAC' from dual
  5       union all select 3,to_date('06-AUG-11','dd-MON-YY'),to_date('22-AUG-11','dd-MON-YY'),'VAC' from dual
  6       union all select 4,to_date('23-AUG-11','dd-MON-YY'),to_date('26-AUG-11','dd-MON-YY'),'VAC' from dual
  7       union all select 5,to_date('27-AUG-11','dd-MON-YY'),to_date('27-AUG-11','dd-MON-YY'),'VAC' from dual
  8  )
  9  ------ end of sample data ------
10  select min(dstart) dstart, max(dend) dend, status, count(*) aggrows
11  from (
12       select
13       id
14            ,dstart
15            ,dend
16            ,status
17            ,dend
18                 -sum(dend-dstart) over (partition by status order by dstart)
19                 -row_number() over (partition by status order by dstart) grp
20       from t
21  )
22  group by grp, status
23* order by grp, status
Scott@my11g SQL>/
DSTART              DEND                STA    AGGROWS
01/07/2009 00:00:00 06/09/2009 00:00:00 VAC          1
20/03/2011 00:00:00 31/03/2011 00:00:00 VAC          1
06/08/2011 00:00:00 27/08/2011 00:00:00 VAC          3

Similar Messages

  • Grouping consecutive rows with same value?

    Hi
    I have a table in which three columns are:
    ROWID  SHOPNAME
    1      SHOP_C     
    2      SHOP_A     
    3      SHOP_C     
    4      SHOP_C     
    5      SHOP_A     
    6      SHOP_A     
    7      SHOP_C     
    8      SHOP_B     
    9      SHOP_B     
    10     SHOP_E    
    11     SHOP_A     
    12     SHOP_D     
    13     SHOP_D     
    14     SHOP_F     
    15     SHOP_G     
    16     SHOP_F     
    17     SHOP_C     
    18     SHOP_C     
    19     SHOP_C     
    20     SHOP_C      Rowid is a primary key column with unique ids
    Shopname is varchar2 column
    I want to make groupings of every "shopname" value "order by ROWID" such that when there are consecutive rows of same shopname the group remains same and as soon as there is different value in shopname column for the next row the "group" changes.
    below is my desired output is with 3rd column of groupings as follows:
    ROWID  SHOPNAME    Groups
    1      SHOP_C      1
    2      SHOP_A      2
    3      SHOP_C      3 ------> same grouping because Shop name is same
    4      SHOP_C      3 ------> same grouping because shop name is same
    5      SHOP_A      4 ----> different shopname so group changed.
    6      SHOP_A      4 ----> same group as above because shopname is same
    7      SHOP_C      5
    8      SHOP_B      6
    9      SHOP_B      6
    10     SHOP_E      7
    11     SHOP_A      8
    12     SHOP_D      9
    13     SHOP_D      9
    14     SHOP_F      10
    15     SHOP_G      11
    16     SHOP_F      12
    17     SHOP_C      13
    18     SHOP_C      13
    19     SHOP_C      13
    20     SHOP_C      13I want that to be done via analytics, so that I can partition by clause for different shops over different cities
    regards
    Ramis.

    with data(row_id, shop) as
    select 1,      'SHOP_C' from dual union all
    select 2,      'SHOP_A' from dual union all     
    select 3,      'SHOP_C' from dual union all
    select 4,      'SHOP_C' from dual union all    
    select 5,      'SHOP_A' from dual union all     
    select 6,      'SHOP_A' from dual union all
    select 7,      'SHOP_C' from dual union all
    select 8,      'SHOP_B' from dual union all
    select 9,      'SHOP_B' from dual union all
    select 10,     'SHOP_E' from dual union all
    select 11,     'SHOP_A' from dual union all
    select 12,     'SHOP_D' from dual union all
    select 13,     'SHOP_D' from dual union all
    select 14,     'SHOP_F' from dual union all
    select 15,     'SHOP_G' from dual union all
    select 16,     'SHOP_F' from dual union all
    select 17,     'SHOP_C' from dual union all
    select 18,     'SHOP_C' from dual union all
    select 19,     'SHOP_C' from dual union all
    select 20,     'SHOP_C' from dual
    get_data as
      select row_id, shop,
             lag(shop) over (order by row_id) prev_shop
        from data
    select row_id, shop,
           sum(case when shop = prev_shop
                      then  0
                      else 1
                      end
                ) over (order by row_id) grps
      from get_data;
    ROW_ID SHOP   GRPS
         1 SHOP_C    1
         2 SHOP_A    2
         3 SHOP_C    3
         4 SHOP_C    3
         5 SHOP_A    4
         6 SHOP_A    4
         7 SHOP_C    5
         8 SHOP_B    6
         9 SHOP_B    6
        10 SHOP_E    7
        11 SHOP_A    8
        12 SHOP_D    9
        13 SHOP_D    9
        14 SHOP_F   10
        15 SHOP_G   11
        16 SHOP_F   12
        17 SHOP_C   13
        18 SHOP_C   13
        19 SHOP_C   13
        20 SHOP_C   13
    20 rows selected

  • Compare two cells in a row and group of rows

    Tuesdays 1st 2nd 3rd 4th 5th MB
    Jan 4, 2011 7 14 21 28 36 32
    Jan 11, 2011 5 15 25 28 38 16
    Jan 18, 2011 2 17 25 28 38 25
    Okay, say the above is my table, how do I compare two cells in a row for two numbers? Say I wanted to find out if row A2 contained a 7 and a 28?
    I thought an IF formula might do it, but can't figure it out.
    Thanks in advance!
    Jim

    Head Crab wrote:
    Tuesdays 1st 2nd 3rd 4th 5th MB
    Jan 4, 2011 7 14 21 28 36 32
    Jan 11, 2011 5 15 25 28 38 16
    Jan 18, 2011 2 17 25 28 38 25
    Okay, say the above is my table, how do I compare two cells in a row for two numbers? Say I wanted to find out if row A2 contained a 7 and a 28?
    "A2" is an address for a single cell, not a row. Its current content, assuming no empty rows above or empty columns left of what's shown, is "Jan 4, 2011". Perhaps you mean Row 2, or the range B2:G2.
    Assuming that you want to know 'if' (or 'how many times') two specific numbers occur in the range of cells from column B to column G in a single row, COUNTIF is the function you want.
    Place the two target numbers into cell I1 and J1.
    Enter the formula below into I2:
    =COUNTIF($B2:$G2,I$1)
    Fill the formula right into J2, then fill both down to row 4.
    You'll get a count of the occurrences of each number.
    If you want only a "Yes" (both numbers appear in the range) or "No" (neither of the numbers appear, or one appears but not the other), use this variation (in I2 or J2):
    =IF(AND(COUNTIF($B2:$G2,I$1)>0,COUNTIF($B2:$G2,J$1)>0),"Yes","No")
    Regards,
    Barry

  • Identifying and reporting Duplicate rows from table

    I want to fetch all the duplicate row from the table and need to report all of it.
    I am trying to run the below query but and not getting the expected output. Please help me.
    Query
    SELECT * FROM ADDT_RPT_REQ A WHERE
    TRIM(A.EMAIL_ADDR) IN
    (SELECT TRIM(EMAIL_ADDR) FROM ADDT_RPT_REQ B
    WHERE TRIM(B.EMAIL_ADDR) = TRIM(A.EMAIL_ADDR)
    AND A.ph_num IN
    (SELECT PH_NUM FROM ADDT_RPT_REQ B
    WHERE TRIM(A.PH_NUM ) = TRIM(B.PH_NUM)
    There are in all 7 columns in the table where id is Unique Id.
    The expected output is something like.
    FST_NAME     LAST_NAME     EMAIL_ADDR     WORK_PH_NUM     ROW_ID     LAST_UPD     BU_ID
    VALERIE     HALL     [email protected]     7819370177     2-21N-4312     31-AUG-04     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4327     29-JAN-04     0-R9NH
    VALERIE     HALL     [email protected]     6034272034     2-21N-4309     04-APR-03     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4317     04-APR-03     0-R9NH
    VALERIE     HALL     [email protected]     8563748820     2-21N-4329     31-AUG-04     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4319     04-APR-03     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4326     04-APR-03     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4324     04-APR-03     0-R9NH
    VALERIE     HALL     [email protected]     8604237395     2-21N-4330     31-AUG-04     0-R9NH
    VALERIE     HALL     [email protected]     7819373731     2-21N-4314     31-AUG-04     0-R9NH
    VALERIE     HALLORAN     [email protected]     6194771101     2-21N-4331     31-OCT-05     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4316     04-APR-03     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4321     04-APR-03     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     7-1W4N-293     15-MAY-04     0-R9NH
    VALERIE     HALL     [email protected]     2032341604     2-21N-4307     31-AUG-04     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4325     04-APR-03     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     2-21N-4315     29-JAN-03     0-R9NH
    VALERIE     HALL     [email protected]     7819373737     7-1W4N-291     15-MAY-04     0-R9NH
    VALERIE     HALLORAN     [email protected]     6194771101     2-21N-4332     31-OCT-05     0-R9NH
    VALERIE     HALL     [email protected]     6038885349     2-21N-4310     31-AUG-04     0-R9NH
    VALERIE     HALL     [email protected]     7819373737324     2-21N-4328     31-AUG-04     0-R9NH
    VALERIE     HALL     [email protected]     7819370177324     2-21N-4313     31-AUG-04     0-R9NH

    Hi again!
    Try that:
    SELECT rowid, fst_name, last_name, email_addr, work_ph_num, row_id, last_upd, bu_id
    FROM ADDT_RPT_REQ A
    WHERE rowid > (SELECT MIN(rowid)
                   FROM ADDT_RPT_REQ B
                   WHERE B.fst_name = A.fst_name
                     AND B.last_name = A.last_name
                     AND B.email_addr = A.email_addr
                     AND B.work_ph_num = A.work_ph_num
                     AND B.row_id = A.row_id
                     AND B.last_upd = A.last_upd
                     AND B.bu_id = A.bu_id);This query should show you all duplicate rows. Use the rowid and DELETE to get rid of these rows.
    DELETE FROM addt_rpt_req A
    WHERE rowid IN (SELECT rowid
                    FROM   (SELECT rowid, row_number() OVER (PARTITION BY fst_name, last_name, email_addr, work_ph_num, row_id, last_upd, bu_id
                                                             ORDER BY row_id) dup
                            FROM addt_rpt_req)
                            WHERE dup > 1);Yours sincerely
    Florian W.
    Edited by: Florian W. on 17.06.2009 14:17

  • Calculate date differences in consecutive rows and generate a sequence

    Hi Guys,
    I am trying to implement one scenario where in i need to compare the date differences for consecutive rows and generate a sequence against that.
    this is the table schema:
    create table temp
    id int identity(1,1),
    emp_id int,
    time datetime
    insert into temp 
    values
    (1, '2011-02-20 12:30:00.000'),
    (1, '2011-02-20 12:32:34.172'),
    (1, '2011-02-20 12:32:34.172'),
    (1, '2011-02-20 12:43:21.004'),
    (1, '2011-02-20 12:46:39.745'),
    (2, '2011-02-20 12:48:06.004'),
    (2, '2011-02-20 12:48:06.004'),
    (2, '2011-02-20 12:53:07.733'),
    (2, '2011-02-20 12:55:30.295');
    now, I want to compare the first date-time with the second and so on. now if the date-time difference is same for two consecutive rows then the sequence should  increment by 1 otherwise the sequence again will start from '00' for any unique date-time.
    This sequence number should start from '00' from each employee.
    I want the output to be like this
    ID emp_id
    time    
    sequence
    1 1 2011-02-20 12:30:00.000
    00
    2  1 2011-02-20 12:32:34.172
    00
    3  1 2011-02-20 12:32:34.172
    01
    4  1 2011-02-20 12:32:34.172
    02
    5  1 2011-02-20 12:46:39.745
    00
    6  2 
    2011-02-20 12:48:06.004 00
    7  2 
    2011-02-20 12:48:07.003 00
    8  2 
    2011-02-20 12:48:07.003 01
    9  2 
    2011-02-20 12:46:39.745 00
    Please revert as soon as possible as this is a bit urgent.
    Thank You in Advance. :)

    create table temp
    (id int identity(1,1),
     emp_id int,
     time datetime
    insert into temp values
    (1, '20110220 12:30:00.000'),
    (1, '20110220 12:32:34.172'),
    (1, '20110220 12:32:34.172'),
    (1, '20110220 12:43:21.004'),
    (1, '20110220 12:46:39.745'),
    (2, '20110220 12:48:06.004'),
    (2, '20110220 12:48:06.004'),
    (2, '20110220 12:53:07.733'),
    (2, '20110220 12:55:30.295');
    go
    SELECT id, emp_id, time,
           dateadd(mcs, (row_number() OVER(PARTITION BY emp_id, time ORDER BY
    id) - 1) * 10,
                   convert(datetime2(5), time)) AS [Sequence]
    FROM   temp
    ORDER  BY id
    go
    DROP TABLE temp
    Erland Sommarskog, SQL Server MVP, [email protected]

  • Using member sorting and grouping with two reports sharing rows

    Hi!
    I have a problem with one report and I need some help or advise here.
    I have two dimensions with dynamic expansion in rows (PRODUCT, MATERIAL), and I use the option Member Sorting and Grouping at Member selector to obtain the total amount of PRODUCT group by PARENTH1:
    PRODUCT               MATERIAL          AMOUNT
    TOTAL PROD_A-X                                   100
    PROD_A_A             MAT1                          22
    PROD_A_B             MAT1                          50
    PROD_A_A             MAT2                          28 
    TOTAL PROD_B-X                                   120
    PROD_B_A             MAT1                          30
    PROD_B_A             MAT2                          50
    PROD_B_B             MAT2                          40
    This works fine if I only have one report, but I need to create another one sharing the row and page axis with the Default Report, when I do that the option Member Sorting and Grouping doesn't work. I really need to have two reports with shared rows and also the summation by PARENTH1, how can I do that?
    Thank you very much

    Hi!
    I have a problem with one report and I need some help or advise here.
    I have two dimensions with dynamic expansion in rows (PRODUCT, MATERIAL), and I use the option Member Sorting and Grouping at Member selector to obtain the total amount of PRODUCT group by PARENTH1:
    PRODUCT               MATERIAL          AMOUNT
    TOTAL PROD_A-X                                   100
    PROD_A_A             MAT1                          22
    PROD_A_B             MAT1                          50
    PROD_A_A             MAT2                          28 
    TOTAL PROD_B-X                                   120
    PROD_B_A             MAT1                          30
    PROD_B_A             MAT2                          50
    PROD_B_B             MAT2                          40
    This works fine if I only have one report, but I need to create another one sharing the row and page axis with the Default Report, when I do that the option Member Sorting and Grouping doesn't work. I really need to have two reports with shared rows and also the summation by PARENTH1, how can I do that?
    Thank you very much

  • Can anybody help....SQL to display row as column and column as rows

    Can anybody help in writing a SQL to display row as column and column as rows?
    Thanks

    check this link:
    Re: Creating Views - from rows to a new column?

  • Will SCCM 2012 R2 , SCOM 2012 R2 and SCDPM R2 2012 support SQL 2012 AlwaysOn Availability Group ?

    Will SCCM 2012 R2 , SCOM 2012 R2 and SCDPM R2 2012 support SQL 2012 AlwaysOn Availability Group ?

    Hi,
    It is listed here:
    http://technet.microsoft.com/en-us/library/dn281933.aspx
    Configuration Manager 2012 r2 and DPM 2012 r2 does not support AlwaysOn.
    regards,
    Jörgen
    -- My System Center blog ccmexec.com -- Twitter
    @ccmexec

  • Getting first row in a group by order by sql

    Hi all,
    I'm having problems with the query below. What I want is to get a count of hotelid and group it then take the top result. My problem is that the version of oracle that I'm using is giving me errors because of the nested group by, order by. Is there any way around this?
    SELECT *
    FROM (SELECT agentid, hotelid, COUNT(hotelid) AS COUNT
    FROM akorders a, akworklist_summary b
    WHERE a.agentid = 1408946 AND
    a.akorderid = b.akorderid
    GROUP BY agentid, hotelid
    ORDER BY COUNT DESC)
    WHERE ROWNUM < 2
    TIA!
    Brian

    SELECT agentid, hotelid, COUNT(hotelid) AS COUNT
    FROM akorders a, akworklist_summary b
    WHERE a.agentid = 1408946 AND
    a.akorderid = b.akorderid
    GROUP BY agentid, hotelid
    HAVING COUNT(*) = (SELECT MAX(icount)
                       FROM (SELECT agentid, hotelid, COUNT(hotelid) AS icount
                             FROM akorders a, akworklist_summary b
                             WHERE a.agentid = 1408946 AND
                                   a.akorderid = b.akorderid
                                   GROUP BY agentid, hotelid ))

  • Convert Column to rows using  sql

    My client relies on a legacy system which currently outputs data in the following format:
    001
    100test1
    110addr1
    115addr2
    120city
    125state
    999drr
    001
    100test1
    110addr1
    115addr2
    120city
    125state
    130XXX
    135YYY
    140ZZZ
    999drr
    001
    100test1
    110addr1
    115addr2
    120city
    125state
    145AAA
    150BBB
    155CCC
    999drr
    I want to transform the above data into the format, as shown below:
    Name | ADDR1 | ADDR2 | CITY | STATE | ColX | ColY | ColZ | ColA | ColB | ColC | .... | LastCol
    100test1 | 110addr1 | 115addr2 | 120city | 125state | null | null | null | null | null | null | ... | null
    100test1 | 110addr1 | 115addr2 | 120city | 125state | 130XXX | 135YYY | 140ZZZ | null | null | null | ... | null
    100test1 | 110addr1 | 115addr2 | 120city | 125state | null | null | null | 145AAA| 150BBB | 155CCC | ... |null |
    When I tried , it only works when the number of rows between '001' and '999' is fixed. But, in my case, the data I get is never fixed and there can be any number of rows in betweeen '001' and '999' and The rows with null values do not show up at all in the flatfile (as shown above in the third block).
    Can anyone help about how to achieve this kind of data transformation ? What sequence of steps or scripts do I have to run to get this?
    Any help is appreciated.
    Thanks ahead
    prema

    I have considered that 7 consecutive rows forms one record. Change the 7 in the query according to your actual data.
    SQL> with t
      2  as
      3  (
      4  select '001' detail from dual
      5  union all
      6  select '100test1' from dual
      7  union all
      8  select '110addr1' from dual
      9  union all
    10  select '115addr2' from dual
    11  union all
    12  select '120city' from dual
    13  union all
    14  select '125state' from dual
    15  union all
    16  select '999drr' from dual
    17  union all
    18  select '002' from dual
    19  union all
    20  select '200test2' from dual
    21  union all
    22  select '210addr1' from dual
    23  union all
    24  select '215addr2' from dual
    25  union all
    26  select '220city' from dual
    27  union all
    28  select '225state' from dual
    29  union all
    30  select '999drr' from dual
    31  union all
    32  select '003' from dual
    33  union all
    34  select '300test1' from dual
    35  union all
    36  select '310addr1' from dual
    37  union all
    38  select '315addr2' from dual
    39  union all
    40  select '320city' from dual
    41  union all
    42  select '325state' from dual
    43  union all
    44  select '999drr' from dual
    45  )
    46  select ltrim(max(sys_connect_by_path(detail,'|')),'|')
    47  from
    48  (
    49         select row_num,
    50                trunc(abs(decode(row_num-rownum,0,1,row_num-rownum))/7)+1 row_num1,
    51                detail
    52      from
    53          (
    54          select decode(mod(rownum,7),0,7,mod(rownum,7)) row_num,detail
    55          from t
    56          )
    57  )
    58  start with row_num=1
    59  connect by row_num-1=prior row_num
    60  and row_num1= PRIOR row_num1
    61  group by row_num1
    62  /
    LTRIM(MAX(SYS_CONNECT_BY_PATH(DETAIL,'|')),'|')
    001|100test1|110addr1|115addr2|120city|125state|999drr
    002|200test2|210addr1|215addr2|220city|225state|999drr
    003|300test1|310addr1|315addr2|320city|325state|999drrRegards,
    Mohana

  • Query to list all Oracle Identifiers and all_oracle_reserved_ words

    can anyone tell me how to retrieve all reserved identifiers and keywords in oracle ???

    In SQL*Plus you can simply do...
    SQL> help reserved words
    RESERVED WORDS (PL/SQL)
    PL/SQL Reserved Words have special meaning in PL/SQL, and may not be used
    for identifier names (unless enclosed in "quotes").
    An asterisk (*) indicates words are also SQL Reserved Words.
    ALL*            DESC*           JAVA            PACKAGE         SUBTYPE
    ALTER*          DISTINCT*       LEVEL*          PARTITION       SUCCESSFUL*
    AND*            DO              LIKE*           PCTFREE*        SUM
    ANY*            DROP*           LIMITED         PLS_INTEGER     SYNONYM*
    ARRAY           ELSE*           LOCK*           POSITIVE        SYSDATE*
    AS*             ELSIF           LONG*           POSITIVEN       TABLE*
    ASC*            END             LOOP            PRAGMA          THEN*
    AT              EXCEPTION       MAX             PRIOR*          TIME
    AUTHID          EXCLUSIVE*      MIN             PRIVATE         TIMESTAMP
    AVG             EXECUTE         MINUS*          PROCEDURE       TIMEZONE_ABBR
    BEGIN           EXISTS*         MINUTE          PUBLIC*         TIMEZONE_HOUR
    BETWEEN*        EXIT            MLSLABEL*       RAISE           TIMEZONE_MINUTE
    BINARY_INTEGER  EXTENDS         MOD             RANGE           TIMEZONE_REGION
    BODY            EXTRACT         MODE*           RAW*            TO*
    BOOLEAN         FALSE           MONTH           REAL            TRIGGER*
    BULK            FETCH           NATURAL         RECORD          TRUE
    BY*             FLOAT*          NATURALN        REF             TYPE
    CHAR*           FOR*            NEW             RELEASE         UI
    CHAR_BASE       FORALL          NEXTVAL         RETURN          UNION*
    CHECK*          FROM*           NOCOPY          REVERSE         UNIQUE*
    CLOSE           FUNCTION        NOT*            ROLLBACK        UPDATE*
    CLUSTER*        GOTO            NOWAIT*         ROW*            USE
    COALESCE        GROUP*          NULL*           ROWID*          USER*
    COLLECT         HAVING*         NULLIF          ROWNUM*         VALIDATE*
    COMMENT*        HEAP            NUMBER*         ROWTYPE         VALUES*
    COMMIT          HOUR            NUMBER_BASE     SAVEPOINT       VARCHAR*
    COMPRESS*       IF              OCIROWID        SECOND          VARCHAR2*
    CONNECT*        IMMEDIATE*      OF*             SELECT*         VARIANCE
    CONSTANT        IN*             ON*             SEPERATE        VIEW*
    CREATE*         INDEX*          OPAQUE          SET*            WHEN
    CURRENT*        INDICATOR       OPEN            SHARE*          WHENEVER*
    CURRVAL         INSERT*         OPERATOR        SMALLINT*       WHERE*
    CURSOR          INTEGER*        OPTION*         SPACE           WHILE
    DATE*           INTERFACE       OR*             SQL             WITH*
    DAY             INTERSECT*      ORDER*          SQLCODE         WORK
    DECIMAL*        INTERVAL        ORGANIZATION    SQLERRM         WRITE
    DECLARE         INTO*           OTHERS          START*          YEAR
    DEFAULT*        IS*             OUT             STDDEV          ZONE
    DELETE*         ISOLATION
    RESERVED WORDS (SQL)
    SQL Reserved Words have special meaning in SQL, and may not be used for
    identifier names unless enclosed in "quotes".
    An asterisk (*) indicates words are also ANSI Reserved Words.
    Oracle prefixes implicitly generated schema object and subobject names
    with "SYS_". To avoid name resolution conflict, Oracle discourages you
    from prefixing your schema object and subobject names with "SYS_".
    ACCESS          DEFAULT*         INTEGER*        ONLINE          START
    ADD*            DELETE*          INTERSECT*      OPTION*         SUCCESSFUL
    ALL*            DESC*            INTO*           OR*             SYNONYM
    ALTER*          DISTINCT*        IS*             ORDER*          SYSDATE
    AND*            DROP*            LEVEL*          PCTFREE         TABLE*
    ANY*            ELSE*            LIKE*           PRIOR*          THEN*
    AS*             EXCLUSIVE        LOCK            PRIVILEGES*     TO*
    ASC*            EXISTS           LONG            PUBLIC*         TRIGGER
    AUDIT           FILE             MAXEXTENTS      RAW             UID
    BETWEEN*        FLOAT*           MINUS           RENAME          UNION*
    BY*             FOR*             MLSLABEL        RESOURCE        UNIQUE*
    CHAR*           FROM*            MODE            REVOKE*         UPDATE*
    CHECK*          GRANT*           MODIFY          ROW             USER*
    CLUSTER         GROUP*           NOAUDIT         ROWID           VALIDATE
    COLUMN          HAVING*          NOCOMPRESS      ROWNUM          VALUES*
    COMMENT         IDENTIFIED       NOT*            ROWS*           VARCHAR*
    COMPRESS        IMMEDIATE*       NOWAIT          SELECT*         VARCHAR2
    CONNECT*        IN*              NULL*           SESSION*        VIEW*
    CREATE*         INCREMENT        NUMBER          SET*            WHENEVER*
    CURRENT*        INDEX            OF*             SHARE           WHERE
    DATE*           INITIAL          OFFLINE         SIZE*           WITH*
    DECIMAL*        INSERT*          ON*             SMALLINT*
    SQL>although I don't think this works in SQL*Developer

  • How to get the last transaction in a row in SQL Developer?

    What syntax would I use to get the last transaction of a row in SQL developer?
    The way I have my query set-up currently it is not returning the correct data, here is my current syntax:
    select ssn, max(tran_id), chng_type,tran_id
    from pda_tran
    where ssn = 'xxx-xxx-0011'
    and chng_type = 'C'
    group by ssn, chng_type,tran_id;
    It returns a 'C' chng_type but it is not the last one. when I query on this ssn this is what I get:
    ssn tran_id chng_type
    xxx-xxx-0011 001 A
    xxx-xxx-0011 002 E
    xxx-xxx-0011 003 C
    xxx-xxx-0011 004 S
    xxx-xxx-0011 005 C
    xxx-xxx-0011 006 T
    I only want to return the ssn's with a last transaction chng_type of 'C'. How can I get the correct information returned. Please advise.

    From what I see and read... there is one to many group by
    You wrote
    select ssn, max(tran_id), chng_type,tran_id
    from pda_tran
    where ssn = 'xxx-xxx-0011'
    and chng_type = 'C'
    group by ssn, chng_type,tran_id;
    If you want the max(tran_id), remove it from the "group by"
    select ssn, chng_type, max(tran_id)
    FROM
    (SELECT 'xxx-xxx-0011' ssn, '001' tran_id, 'A' chng_type FROM DUAL UNION
    SELECT 'xxx-xxx-0011' ssn, '002' tran_id, 'E' chng_type FROM DUAL UNION
    SELECT 'xxx-xxx-0011' ssn, '003' tran_id, 'C' chng_type FROM DUAL UNION
    SELECT 'xxx-xxx-0011' ssn, '004' tran_id, 'S' chng_type FROM DUAL UNION
    SELECT 'xxx-xxx-0011' ssn, '005' tran_id, 'C' chng_type FROM DUAL UNION
    SELECT 'xxx-xxx-0011' ssn, '006'tran_id, 'T' chng_type FROM DUAL )
    where ssn = 'xxx-xxx-0011'
    and chng_type = 'C'
    group by ssn, chng_type;

  • Picking a Max value row out of a group of rows.

    Hi,
    I'm using Oracle 10.2.0.4.0
    For some reason I can't come up with a way to pick out a simple row that contains the max date value out of a group of sub group of rows. The following rows are one group of the result of a complex view ordered by ACCOUNT_NUMBER. I'm just showing the first group for Demo Purposes.
    CUSTOMER_NAME          ACCOUNT_NUMBER     BOOKED_DATES     OUTSTANDING_APPROVALS     BOOKED_NOT_BILLED         SALES
    ABC company, LLC     114943          05/22/2008                   11:17:05           100,072.43          100,072.43
    ABC company, LLC     114943          06/30/2008                   15:12:29           129,956.00          129,956.00
    ABC company, LLC     114943          07/30/2008                   15:57:16           10,957.00          10,957.00This is just the first of many groups in this view. I just need a simple way to select the row with the max BOOKED_DATES. I've tried everything I could think of but the other two rows are not going away. MAX(BOOKED_DATES) is not working in the HAVING section. I just want my out output to be the rows out of each group with the most recent BOOKED_DATES.
    Therefor , my output would be
    CUSTOMER_NAME          ACCOUNT_NUMBER     BOOKED_DATES     OUTSTANDING_APPROVALS     BOOKED_NOT_BILLED         SALES
    ABC company, LLC     114943          07/30/2008                   15:57:16           10,957.00          10,957.00for ACCOUNT_NUMBER 114943. For the truly curious, the query is below. I'm sure the solution is simple but not to me this day. Maybe it's a Monday thing.
    Thanks in Advance.
    select  distinct
    party.party_name CUSTOMER_NAME, --"Customer Name"
    cust_acct.account_number ACCOUNT_NUMBER,--"Account Number"
    max(h.BOOKED_DATE)  BOOKED_DATES,-- "Booked Dates",
    osa.OUTSTANDING_SALE_AMT    OUTSTANDING_APPROVALS,--"Outstanding Approvals",
    ola2.BOOKED_NOT_BILLED                                     BOOKED_NOT_BILLED,
    --ola.line_id,
    --h.header_id,
    sum(nvl(ola.ORDERED_QUANTITY,0) * nvl(ola.UNIT_LIST_PRICE,0))   SALES,
    CASE
       WHEN
       invoiced_amt_info.TERMS = 'Current'
        THEN invoiced_amt_info.CURRENT_INV  
       ELSE NULL
    END  "CURRENT_IA",--"Current",
    CASE
       WHEN
       invoiced_amt_info.TERMS = 'Current'
        THEN invoiced_amt_info.CURRENT_TAX 
       ELSE NULL
    END CURRENT_TAX,--"Current Tax",
    CASE
       WHEN
       invoiced_amt_info.TERMS = '1-30 days'
        THEN invoiced_amt_info.CURRENT_INV 
       ELSE NULL
    END     LT_30_DAYS,--  "1-30 Days",
    CASE
       WHEN
       invoiced_amt_info.TERMS = '1-30 days'
        THEN invoiced_amt_info.CURRENT_TAX  
       ELSE NULL
    END     LT_30_DAYS_TAX,-- "1-30 Days Tax",
    CASE
       WHEN
       invoiced_amt_info.TERMS = '31-60 days'
        THEN invoiced_amt_info.CURRENT_INV 
       ELSE NULL 
    END     LT_60_DAYS,-- "1-60 Days",
    CASE
       WHEN
       invoiced_amt_info.TERMS = '31-60 days'
        THEN invoiced_amt_info.CURRENT_TAX
       ELSE NULL
    END     LT_60_DAYS_TAX,--"1-60 Days Tax",
    CASE
       WHEN
       invoiced_amt_info.TERMS = '61-90 days'
        THEN invoiced_amt_info.CURRENT_INV  
       ELSE NULL
    END     LT_90_DAYS,-- "1-90 Days",
    CASE
       WHEN
       invoiced_amt_info.TERMS = '61-90 days'
        THEN invoiced_amt_info.CURRENT_TAX 
       ELSE NULL
    END     LT_90_DAYS_TAX,-- "1-90 Days Tax",
    CASE
       WHEN
       invoiced_amt_info.TERMS = '90+ days'
        THEN invoiced_amt_info.CURRENT_INV  
       ELSE NULL 
    END     MT_90_PLUS_DAYS,-- "90+ Days",
    CASE
       WHEN
       invoiced_amt_info.TERMS = '90+ days'
        THEN invoiced_amt_info.CURRENT_TAX
       ELSE NULL
    END     MT_90_PLUS_DAYS_TAX,--"90+ Days Tax",
    uc.UNAPPLIED_CASH UNAPPLIED_CASH--"Unapplied Cash"
    FROM
    oe_order_headers_all        h,
    hz_cust_accounts            cust_acct,
    hz_parties                  party,
    hz_customer_profiles        cust_prof,
    oe_order_lines_all ola,
    select l.HEADER_ID HEADER_ID,
    l.sold_to_org_id SOLD_TO_ORG_ID,
    sum(nvl(l.ORDERED_QUANTITY,0) * nvl(l.UNIT_LIST_PRICE,0)) BOOKED_NOT_BILLED
    from
    oe_order_lines_all l
    where
        l.BOOKED_FLAG <> 'N'
    AND l.FLOW_STATUS_CODE <> 'CANCELLED'
    AND l.INVOICE_INTERFACE_STATUS_CODE <> 'NO'
    group by l.HEADER_ID, l.sold_to_org_id
    ) ola2,
    select INV_AMT.aginglayer, INV_AMT.aging TERMS, sum(INV_AMT.due_amount) CURRENT_INV, INV_AMT.CUSTOMER_ID,--due_amount,--invoiced ammount Currrent
              sum(INV_AMT.tax_amount) CURRENT_TAX --tax_amount
               from (
                    select  
                            c.customer_name
                          , c.customer_number
                          , c.CUSTOMER_ID
                          , sum(ps.amount_due_remaining) due_amount
                          , sum(ps.tax_remaining) tax_amount
                          , 'Current' aging
                          , 1 aginglayer
                          , 1 showord
                     from ra_customers c
                          , ar_payment_schedules_all ps
                     where ps.status = 'OP'
                       and ps.class <> 'PMT'
                       and trunc(sysdate - ps.due_date) < 1
                       and ps.customer_id = c.customer_id
                     group by c.customer_name
                             , c.customer_number
                             , c.CUSTOMER_ID
                    union
                    select   
                            c.customer_name
                          , c.customer_number
                          , c.CUSTOMER_ID                     
                          , sum(ps.amount_due_remaining) due_amount
                          , sum(ps.tax_remaining) tax_amount
                          , '1-30 days' aging
                          , 2 aginglayer
                          , 2 showord
                     from ra_customers c
                          , ar_payment_schedules_all ps
                     where ps.status = 'OP'
                       and ps.class <> 'PMT'
                       and trunc(sysdate - ps.due_date) >= 1
                       and trunc(sysdate - ps.due_date) <= 30
                       and ps.customer_id = c.customer_id
                     group by c.customer_name
                             , c.customer_number
                             , c.CUSTOMER_ID                     
                    union
                    select  
                            c.customer_name
                          , c.customer_number
                          , c.CUSTOMER_ID                     
                          , sum(ps.amount_due_remaining) due_amount
                          , sum(ps.tax_remaining) tax_amount
                          , '31-60 days' aging
                          , 3 aginglayer
                          , 3 showord
                     from ra_customers c
                          , ar_payment_schedules_all ps
                     where ps.status = 'OP'
                       and ps.class <> 'PMT'
                       and trunc(sysdate - ps.due_date) > 30
                       and trunc(sysdate - ps.due_date) <= 60
                       and ps.customer_id = c.customer_id
                     group by c.customer_name
                             , c.customer_number
                             , c.CUSTOMER_ID
                    union
                    select  
                            c.customer_name
                          , c.customer_number
                          , c.CUSTOMER_ID                     
                          , sum(ps.amount_due_remaining) due_amount
                          , sum(ps.tax_remaining) tax_amount
                          , '61-90 days' aging
                          , 4 aginglayer
                          , 4 showord
                     from ra_customers c
                          , ar_payment_schedules_all ps
                     where ps.status = 'OP'
                       and ps.class <> 'PMT'
                       and trunc(sysdate - ps.due_date) > 60
                       and trunc(sysdate - ps.due_date) <= 90
                       and ps.customer_id = c.customer_id
                     group by c.customer_name
                             , c.customer_number
                             , c.CUSTOMER_ID                        
                    union
                    select  
                            c.customer_name
                          , c.customer_number
                          , c.CUSTOMER_ID                     
                          , sum(ps.amount_due_remaining) due_amount
                          , sum(ps.tax_remaining) tax_amount
                          , '90+ days' aging
                          , 5 aginglayer
                          , 5 showord
                     from ra_customers c
                          , ar_payment_schedules_all ps
                          , ra_customer_trx_all trx
                          , ra_cust_trx_types_all types
                     where ps.status = 'OP'
                       and ps.class <> 'PMT'
                       and trunc(sysdate - ps.due_date) > 90
                       and ps.customer_id = c.customer_id
                       and trx.customer_trx_id = ps.customer_trx_id
                       and types.cust_trx_type_id = trx.cust_trx_type_id
                       and types.name <> 'CSG-Conversion Pmt'
                       and types.org_id= 1
                     group by c.customer_name
                             , c.customer_number
                             , c.CUSTOMER_ID
                    ) INV_AMT
                 group by aginglayer, aging, showord, INV_AMT.CUSTOMER_ID
    ) invoiced_amt_info,
    select   ra_cust.customer_name CUSTOMER_NAME, ra_cust.customer_number CUSTOMER_NUMBER, ra_cust.customer_id CUSTOMER_ID,
                     sum(pay_sched.amount_due_remaining) UNAPPLIED_CASH
               from  ra_customers ra_cust
                    , ar_payment_schedules_all pay_sched
               where
                 pay_sched.status = 'OP'
                 and pay_sched.class = 'PMT'
                 and pay_sched.due_date > trunc(sysdate - 365)
                 and pay_sched.customer_id = ra_cust.customer_id
               group by ra_cust.customer_name, ra_cust.CUSTOMER_NUMBER, ra_cust.CUSTOMER_ID
    ) uc,
    select   qh.cust_account_id CUST_ACCOUNT_ID,    sum(qh.total_quote_price) OUTSTANDING_SALE_AMT
    from ASO_QUOTE_HEADERS_ALL qh,ASO_QUOTE_STATUSES_TL st
    where st.quote_status_id = qh.quote_status_id
    and st.meaning ='Credit Hold'
    group by qh.cust_account_id
    ) osa          
    Where 
         h.HEADER_ID = ola.HEADER_ID
    AND h.HEADER_ID = ola2.HEADER_ID
    AND ola.sold_to_org_id = cust_acct.cust_account_id(+)
    AND ola2.sold_to_org_id = ola.sold_to_org_id(+)
    AND cust_acct.party_id = party.party_id(+)
    AND cust_acct.CUST_ACCOUNT_ID = cust_prof.CUST_ACCOUNT_ID(+)
    AND cust_prof.party_id = party.party_id
    AND cust_prof.CUST_ACCOUNT_ID = invoiced_amt_info.CUSTOMER_ID(+)
    AND cust_prof.CUST_ACCOUNT_ID = uc.CUSTOMER_ID(+)
    AND cust_prof.CUST_ACCOUNT_ID = osa.CUST_ACCOUNT_ID(+)
    group by  party.party_name, cust_acct.account_number, invoiced_amt_info.TERMS, osa.OUTSTANDING_SALE_AMT,
    ola2.BOOKED_NOT_BILLED,
    invoiced_amt_info.CURRENT_INV,
    invoiced_amt_info.CURRENT_TAX, uc.UNAPPLIED_CASH
    order by party.party_name

    Example
    --Sample Data
    SQL>select deptno, empno, sal,
      2     max(sal) over ( partition by deptno order by deptno) mv
      3* from emp
    SQL> /
        DEPTNO      EMPNO        SAL         MV
            10       7782       2450       5000
            10       7839       5000       5000
            10       7934       1300       5000
            20       7566       2975       3000
            20       7902       3000       3000
            20       7876       1100       3000
            20       7369        800       3000
            20       7788       3000       3000
            30       7521       1250       2850
            30       7844       1500       2850
            30       7499       1600       2850
            30       7900        950       2850
            30       7698       2850       2850
            30       7654       1250       2850
    14 rows selected.
    SQL>select * from
      2  (
      3  select deptno, empno, sal,
      4     max(sal) over ( partition by deptno order by deptno) mv
      5  from emp
      6* ) where sal = mv
    SQL> /
        DEPTNO      EMPNO        SAL         MV
            10       7839       5000       5000
            20       7902       3000       3000
            20       7788       3000       3000
            30       7698       2850       2850SS

  • How to use group by in PL/SQL

    Can anyone give me a clue how to group rows using PL/SQL? I want to make a push button that groups a number of rows. When I run the form and push the button, I get the Oracle 01422 error. I am using one data block and, after pressing execute on the Oracle form in the web browser, I want to sort the rows using the group by clause as a pl sql trigger in a push button (with the WHEN BUTTON PRESSED trigger). I am new to Oracle Forms.

    I managed to use a cursor to access and display each row. I have to press the command button I created once for access of each row individually. I want to be able to push the button once, and populate each row with a record from my table. I am using the tabular format. Here is my code:
    DECLARE
         CURSOR email_message_cur
         IS
              SELECT sender, subject, body, date_time_sent
              FROM Email_Message
              ORDER BY sender;
    BEGIN
         OPEN email_message_cur;
         FETCH email_message_cur
         INTO :GROUP_EMAIL_MESSAGE.SENDER, :GROUP_EMAIL_MESSAGE.SUBJECT, :GROUP_EMAIL_MESSAGE.BODY, :GROUP_EMAIL_MESSAGE.DATE_TIME_SENT;
         WHILE email_message_cur%FOUND LOOP
              IF :GROUP_EMAIL_MESSAGE.SENDER IS NOT NULL THEN
                   CREATE_RECORD;
              END IF;
              FETCH email_message_cur INTO :GROUP_EMAIL_MESSAGE.SENDER, :GROUP_EMAIL_MESSAGE.SUBJECT, :GROUP_EMAIL_MESSAGE.BODY, :GROUP_EMAIL_MESSAGE.DATE_TIME_SENT;
         END LOOP;
         CLOSE email_message_cur;
    END;

  • Retrieve n and n-1 rows on the same line

    In a database I am trying to get the latest employee information and the previous entry. The latest entry can be determined by the fact that DATEFIN is empty and the previous entry is returned by MAX(DATEFIN). All previous entries have a DATEFIN value
    So I wrote a query which returned both the lines per employee. i.e. n and n-1
    Actually what is needed is to compare certain fields of each line, so I need to show employee n and n-1 on the same line. This time I used LEAD so emp,date,field1,Lead(field1,1) etc etc.
    As all the employee lines are returned, I used a minus function to remove all those where the DATEFIN IS NOT NULL, given that the LEAD line returned the information required BEFORE the minus removed it.
    However, I am still getting n and n-1 rows, even though the minus part run by itself removes n-1,n-2... rows.
    Question
    How can I structure the minus or LEAD query just to get the n row and n-1 LEAD information
    select trim(to_char(se.idexport,'0999'))
    || '|'
    || sa.referentiel_id
    || '|'
    || sa.idunique
    || '|'
    || sa.matricule
    || '|'
    || sr.niveau
    || '|'
    || LEAD(sr.niveau,1) OVER (ORDER BY sr.salarie_id,sr.datedebut desc )
    || '|'
    || sr.echelon
    || '|'
    || sr.coefficient
    || '|'
    || fo.code
    || '|'
    || sr.salairemensuel
    || '|'
    || sr.tauxhoraire
    || '|'
    || to_CHAR(ca.datevaleurrevisions,'DD/MM/YYYY')
    || '|'
    || em.code
    || '|'
    || fi.code
    || '|'
    || cc.code
    || '|'
    || sr.datedebut
    || '|'
    || LEAD(sr.datedebut,1) OVER (ORDER BY sr.salarie_id,sr.datedebut desc )
    || '|'
    || sr.datefin
    || '|'
    || LEAD(sr.datefin,1) OVER (ORDER BY sr.salarie_id,sr.datedebut desc )
    AS Text
    from salarie sa
    inner join selection_export se on (se.IDUNIQUE = SA.IDUNIQUE AND se.idexport = 42 AND se.exporter = 1)
    inner join salarierevision sr on (SR.SALARIE_ID = se.IDUNIQUE AND SR.ACCESRESTREINT = 0)
    inner join campagne ca on CA.ISANNEEENCOURS = 1
    inner join parambranche pb on (ca.organisationlds_id = pb.organisationlds_id)
    inner join utilisateur u on (u.CODE = 'gagross' AND U.ORGANISATIONLDS_ID = CA.ORGANISATIONLDS_ID)
    left outer join fonction fo on (fo.id = sr.fonction_id)
    left outer join emploi em on (em.id = sr.emploi_id)
    left outer join filiere fi on (fi.id = sr.filiere_id)
    left outer join CONVENTIONCOLLECTIVE cc on (cc.id = sr.CONVENTIONCOLLECTIVE_ID)
    minus
    select trim(to_char(se.idexport,'0999'))
    || '|'
    || sa.referentiel_id
    || '|'
    || sa.idunique
    || '|'
    || sa.matricule
    || '|'
    || sr.niveau
    || '|'
    || LEAD(sr.niveau,1) OVER (ORDER BY sr.salarie_id,sr.datedebut desc )
    || '|'
    || sr.echelon
    || '|'
    || sr.coefficient
    || '|'
    || fo.code
    || '|'
    || sr.salairemensuel
    || '|'
    || sr.tauxhoraire
    || '|'
    || to_CHAR(ca.datevaleurrevisions,'DD/MM/YYYY')
    || '|'
    || em.code
    || '|'
    || fi.code
    || '|'
    || cc.code
    || '|'
    || sr.datedebut
    || '|'
    || LEAD(sr.datedebut,1) OVER (ORDER BY sr.salarie_id,sr.datedebut desc )
    || '|'
    || sr.datefin
    || '|'
    || LEAD(sr.datefin,1) OVER (ORDER BY sr.salarie_id,sr.datedebut desc )
    AS Text
    from salarie sa
    inner join selection_export se on (se.IDUNIQUE = SA.IDUNIQUE AND se.idexport = 42 AND se.exporter = 1)
    inner join salarierevision sr on (SR.SALARIE_ID = se.IDUNIQUE AND SR.ACCESRESTREINT = 0)
    inner join campagne ca on CA.ISANNEEENCOURS = 1
    inner join parambranche pb on (ca.organisationlds_id = pb.organisationlds_id)
    inner join utilisateur u on (u.CODE = 'gagross' AND U.ORGANISATIONLDS_ID = CA.ORGANISATIONLDS_ID)
    left outer join fonction fo on (fo.id = sr.fonction_id)
    left outer join emploi em on (em.id = sr.emploi_id)
    left outer join filiere fi on (fi.id = sr.filiere_id)
    left outer join CONVENTIONCOLLECTIVE cc on (cc.id = sr.CONVENTIONCOLLECTIVE_ID)
    where sr.datefin is not null
    Thanks and I hope this is clear
    Colin

    Assuming that the sr.salarie_id column identifies the employee I think you need to partition by it, not order by it in the analytic functio. If it does not identify the employee, then you need to partition by whatever uniquely identifies an employee. I would likely structure it something like this:
    SQL> with t as (
      2     SELECT 1 emp_id, TO_DATE('01-jul-2010', 'dd-mon-yyyy') dt, 'Jul' descr
      3     from dual union all
      4     SELECT 1, TO_DATE('01-aug-2010', 'dd-mon-yyyy'), 'Aug' from dual union all
      5     SELECT 1, TO_DATE('01-sep-2010', 'dd-mon-yyyy'), 'Sep' from dual union all
      6     SELECT 1, TO_DATE('01-oct-2010', 'dd-mon-yyyy'), 'Oct' from dual union all
      7     SELECT 1, TO_DATE(NULL), 'Current' from dual union all
      8     SELECT 2, TO_DATE('01-jan-2010', 'dd-mon-yyyy'), 'Jan' from dual union all
      9     SELECT 2, TO_DATE('01-mar-2010', 'dd-mon-yyyy'), 'Mar' from dual union all
    10     SELECT 2, TO_DATE('01-may-2010', 'dd-mon-yyyy'), 'May' from dual union all
    11     SELECT 2, TO_DATE('01-jul-2010', 'dd-mon-yyyy'), 'Jul' from dual union all
    12     SELECT 2, TO_DATE(NULL), 'Current' from dual)
    13  SELECT emp_id, curr_dt, last_dt, curr_descr, last_descr
    14  FROM (SELECT emp_id, dt curr_dt,
    15               LEAD(dt) OVER(PARTITION BY emp_id
    16                             ORDER BY dt desc nulls first) last_dt,
    17               descr curr_descr,
    18               LEAD(descr) OVER(PARTITION BY emp_id
    19                             ORDER BY dt desc nulls first) last_descr
    20        FROM t)
    21  WHERE curr_dt IS NULL
        EMP_ID CURR_DT     LAST_DT     CURR_DE LAST_DE
             1             01-OCT-2010 Current Oct
             2             01-JUL-2010 Current JulWhere my t is your set of joined tables without the where sr.datefin is not null predicate.
    John

Maybe you are looking for