Home » SQL & PL/SQL » SQL & PL/SQL » finding the gaps in between the sequences (Oracle 10G)
finding the gaps in between the sequences [message #627487] Wed, 12 November 2014 05:59 Go to next message
SW26477
Messages: 9
Registered: November 2014
Location: Location
Junior Member
Hello All,

I have a query with finding the gap in between the sequences.

Below is the structure of my table
user_number	|    seq_number
1	        |       101
1	        |       102
1		|	109
1		|	110
1		|	111
2		|	201
2		|	202
2		|	203
2		|	207
2		|	208
.		|	.
.		|	.
.		|	.
.		|	.

Now I have to find the gap in between the sequences, what I mean by gap is for user_number '1' there is gap of 6 between seq_number '102' and '109'.
Below is the query which I am trying to write, but not giving the exact answer, it always gives the gap of 2:
select gap_start - gap_end gap
from(
select a.seq_number+1 as gap_start, b.seq_number-1 as gap_end 
from   my_table a, my_table b
where a.seq_number = b.seq_number  
and a.seq_number - (select c.seq_number 
                    from my_table c
                    where c.seq_number = a.seq_number-1) is null
and a.user_number = '1'
order by a.seq_number
);


Thanks.


Edited by Lalit : Added code tags

[Updated on: Wed, 12 November 2014 06:18] by Moderator

Report message to a moderator

Re: finding the gaps in between the sequences [message #627490 is a reply to message #627487] Wed, 12 November 2014 06:17 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Welcome to this forum!

Please read and follow the forum guidelines, to enable us to help you:

http://www.orafaq.com/forum/t/88153/0/ and read http://www.orafaq.com/forum/t/174502/
Re: finding the gaps in between the sequences [message #627491 is a reply to message #627490] Wed, 12 November 2014 06:21 Go to previous messageGo to next message
SW26477
Messages: 9
Registered: November 2014
Location: Location
Junior Member
Thanks Lalit,

Formated my code.

I tried to search in google I am not able to find any answer for it.
Re: finding the gaps in between the sequences [message #627492 is a reply to message #627490] Wed, 12 November 2014 06:24 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Does this help,

SQL> WITH DATA AS(
  2  SELECT 1    user_number, 101 seq_number FROM dual UNION ALL
  3  SELECT 1,      102 FROM dual UNION ALL
  4  SELECT 1,                  109 FROM dual UNION ALL
  5  SELECT 1,                  110 FROM dual UNION ALL
  6  SELECT 1,                  111 FROM dual UNION ALL
  7  SELECT 2,                  201 FROM dual UNION ALL
  8  SELECT 2,                  202 from dual union all
  9  SELECT 2,                  203 FROM dual UNION ALL
 10  SELECT 2,                  207 FROM dual UNION ALL
 11  SELECT 2,                  208 FROM dual)
 12  SELECT user_number,
 13    seq_number,
 14    seq_number - rn diff
 15  FROM
 16    (SELECT user_number,
 17      seq_number,
 18      lag(seq_number) OVER(partition by user_number ORDER BY user_number, seq_number) rn
 19    FROM DATA
 20    )
 21  WHERE seq_number - rn > 1
 22  /

USER_NUMBER SEQ_NUMBER       DIFF
----------- ---------- ----------
          1        109          7
          2        207          4

SQL>


Edit : Added partition by

[Updated on: Wed, 12 November 2014 06:26]

Report message to a moderator

Re: finding the gaps in between the sequences [message #627499 is a reply to message #627487] Wed, 12 November 2014 07:14 Go to previous messageGo to next message
EdStevens
Messages: 1376
Registered: September 2013
Senior Member
https://community.oracle.com/thread/3629664
Re: finding the gaps in between the sequences [message #627500 is a reply to message #627487] Wed, 12 November 2014 07:15 Go to previous messageGo to next message
sandeep_orafaq
Messages: 88
Registered: September 2014
Member
Can you paste the sample output that you need. Sow how it is not clear to me what you want as output.
Re: finding the gaps in between the sequences [message #627524 is a reply to message #627500] Wed, 12 November 2014 10:21 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
@OP, I hope my solution is what you need. In addition, this is going to be a performance issue:

Quote:

and a.user_number = '1'


User_number is a NUMBER and not a string. I assume it to be a primary key being populated using a sequence. So, using single quotes around it will force Oracle to consider it a string, thus an implicit conversion would happen to convert it to a NUMBER.

Edit : typo

[Updated on: Wed, 12 November 2014 10:23]

Report message to a moderator

Re: finding the gaps in between the sequences [message #627525 is a reply to message #627492] Wed, 12 November 2014 10:27 Go to previous messageGo to next message
SW26477
Messages: 9
Registered: November 2014
Location: Location
Junior Member
Thanks Lalit!

Yes this is what I need. But one thing I was trying to add this query in a cursor and the procedure is not complining, it gives below error.

PLS-00103: Encountered the symbol "(" when expecting one of the following:

, from

I am not sure if we can write PARTITION BY in cursor?
Re: finding the gaps in between the sequences [message #627526 is a reply to message #627525] Wed, 12 November 2014 10:30 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Since I can't see anything, I can't help you. Nobody can debug an invisible code Wink
Re: finding the gaps in between the sequences [message #627528 is a reply to message #627526] Wed, 12 November 2014 10:52 Go to previous messageGo to next message
SW26477
Messages: 9
Registered: November 2014
Location: Location
Junior Member
Hi,

Below is my code:

 CREATE OR replace PROCEDURE P_validate_seq (p_gaps_alowed IN NUMBER DEFAULT 1)
IS
  --get the distinct user number
  CURSOR c_user_number IS
    SELECT DISTINCT user_number
    FROM   advices
    WHERE  action_type = 0;
  r_user_number c_user_number%ROWTYPE;
  --calculate the gaps between the sequences based on user number
  CURSOR c_advice_seq (
    p_user_number advices.user_number%TYPE) IS
    SELECT ( advice_sequence_number - rn ) gap
    FROM   (SELECT user_number,
                   action_type,
                   advice_sequence_number,
                   Lag (advice_sequence_number)
                     over (
                       PARTITION BY user_number
                       ORDER BY user_number, advice_sequence_number) rn
            FROM   advices)
    WHERE  advice_sequence_number - rn > 1
           AND user_number = p_user_number
           AND action_type = 0;
  r_advice_seq  c_advice_seq%ROWTYPE;
BEGIN
    FOR r_user_number IN c_user_number LOOP
        FOR r_advice_seq IN c_advice_seq (r_user_number.user_number) LOOP
            IF r_advice_seq.gap > p_gaps_alowed THEN
              dbms_output.Put_line (
              'sequence number should be sequential per user number: '
              || r_user_number.user_number);
            END IF;
        END LOOP;
    END LOOP;
EXCEPTION
  WHEN OTHERS THEN
             g_routine_name := 'p_validate_seq';
END p_validate_seq;
Re: finding the gaps in between the sequences [message #627530 is a reply to message #627528] Wed, 12 November 2014 10:56 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
1. Remove the exception block
2. Compile it in SQL*Plus
3. Use SHOW ERROR
4. Copy and paste the entire thing here using CODE tags
Re: finding the gaps in between the sequences [message #627533 is a reply to message #627530] Wed, 12 November 2014 11:09 Go to previous messageGo to next message
SW26477
Messages: 9
Registered: November 2014
Location: Location
Junior Member
Hi,

Here is the code:

SQL>  CREATE OR replace PROCEDURE P_validate_seq (p_gaps_alowed IN NUMBER DEFAULT 1)
  2  IS
  3    --get the distinct user number
  4    CURSOR c_user_number IS
  5      SELECT DISTINCT user_number
  6      FROM   advices
  7      WHERE  action_type = 0;
  8    r_user_number c_user_number%ROWTYPE;
  9    --calculate the gaps between the sequences based on user number
 10    CURSOR c_advice_seq (
 11      p_user_number advices.user_number%TYPE) IS
 12      SELECT ( advice_sequence_number - rn ) gap
 13      FROM   (SELECT user_number,
 14                     action_type,
 15                     advice_sequence_number,
 16                     Lag (advice_sequence_number)
 17                       over (
 18                         PARTITION BY user_number
 19                         ORDER BY user_number, advice_sequence_number) rn
 20              FROM   advices)
 21      WHERE  advice_sequence_number - rn > 1
 22             AND user_number = p_user_number
 23             AND action_type = 0;
 24    r_advice_seq  c_advice_seq%ROWTYPE;
 25  BEGIN
 26      FOR r_user_number IN c_user_number LOOP
 27          FOR r_advice_seq IN c_advice_seq (r_user_number.user_number) LOOP
 28              IF r_advice_seq.gap > p_gaps_alowed THEN
 29                dbms_output.Put_line (
 30                'sequence number should be sequential per user number: '
 31                || r_user_number.user_number);
 32              END IF;
 33          END LOOP;
 34      END LOOP;
 35  END p_validate_seq;  
 36  /

Warning: Procedure created with compilation errors.

SQL> show errors;
Errors for PROCEDURE P_VALIDATE_SEQ:

LINE/COL ERROR
-------- -----------------------------------------------------------------
17/27    PLS-00103: Encountered the symbol "(" when expecting one of the
         following:
         , from

Re: finding the gaps in between the sequences [message #627535 is a reply to message #627533] Wed, 12 November 2014 11:33 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Post the result of;
select * from v$version;

Re: finding the gaps in between the sequences [message #627538 is a reply to message #627535] Wed, 12 November 2014 11:39 Go to previous messageGo to next message
SW26477
Messages: 9
Registered: November 2014
Location: Location
Junior Member

select * from v$version;

Oracle8i Enterprise Edition Release 8.1.7.2.0 - Production
PL/SQL Release 8.1.7.2.0 - Production
CORE 8.1.7.0.0 Production
TNS for DEC OSF/1 AXP: Version 8.1.7.2.0 - Production
NLSRTL Version 3.4.1.0.0 - Production

[Updated on: Wed, 12 November 2014 11:39]

Report message to a moderator

Re: finding the gaps in between the sequences [message #627543 is a reply to message #627538] Wed, 12 November 2014 11:49 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

In 8i you can't use LAG function in PL/SQL.
Why did you say you are in 10g?

Re: finding the gaps in between the sequences [message #627545 is a reply to message #627543] Wed, 12 November 2014 11:53 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

You have to use EXECUTE IMMEDIATE.

[Edit: add link]

[Updated on: Wed, 12 November 2014 11:55]

Report message to a moderator

Re: finding the gaps in between the sequences [message #627581 is a reply to message #627543] Wed, 12 November 2014 16:34 Go to previous messageGo to next message
SW26477
Messages: 9
Registered: November 2014
Location: Location
Junior Member
Hi,

The problem is dev enviornment is in 8i and live is in 10g, dev will be migrated to 10g in next month and before that my code will be going in live.
So now need to code according to 8i.

Anyways so can we convert below code according to 8i?


SQL>  CREATE OR replace PROCEDURE P_validate_seq (p_gaps_alowed IN NUMBER DEFAULT 1)
  2  IS
  3    --get the distinct user number
  4    CURSOR c_user_number IS
  5      SELECT DISTINCT user_number
  6      FROM   advices
  7      WHERE  action_type = 0;
  8    r_user_number c_user_number%ROWTYPE;
  9    --calculate the gaps between the sequences based on user number
 10    CURSOR c_advice_seq (
 11      p_user_number advices.user_number%TYPE) IS
 12      SELECT ( advice_sequence_number - rn ) gap
 13      FROM   (SELECT user_number,
 14                     action_type,
 15                     advice_sequence_number,
 16                     Lag (advice_sequence_number)
 17                       over (
 18                         PARTITION BY user_number
 19                         ORDER BY user_number, advice_sequence_number) rn
 20              FROM   advices)
 21      WHERE  advice_sequence_number - rn > 1
 22             AND user_number = p_user_number
 23             AND action_type = 0;
 24    r_advice_seq  c_advice_seq%ROWTYPE;
 25  BEGIN
 26      FOR r_user_number IN c_user_number LOOP
 27          FOR r_advice_seq IN c_advice_seq (r_user_number.user_number) LOOP
 28              IF r_advice_seq.gap > p_gaps_alowed THEN
 29                dbms_output.Put_line (
 30                'sequence number should be sequential per user number: '
 31                || r_user_number.user_number);
 32              END IF;
 33          END LOOP;
 34      END LOOP;
 35  END p_validate_seq;  
 36  /
Re: finding the gaps in between the sequences [message #627583 is a reply to message #627581] Wed, 12 November 2014 16:57 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>The problem is dev enviornment is in 8i and live is in 10g,
Foolishness abounds with you folks.
Professional IT folks insist that DEV & PROD be identical environments.

both V8 & V10 are obsoleted & unsupported.
You are now reaping the benefits for the choice to not stay current.

You're On Your Own (YOYO)!
Re: finding the gaps in between the sequences [message #627604 is a reply to message #627581] Thu, 13 November 2014 00:51 Go to previous message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
Anyways so can we convert below code according to 8i?


No, if you have LAG in something that is analyzed by PL/SQL then you can't.
But is it smart to try to workaround good code to make it work in 8i and deliver bad code?

Previous Topic: Achieving Report Format in PL/SQL or SQL
Next Topic: extract sql statements from trace file in windows environment
Goto Forum:
  


Current Time: Thu Apr 25 14:14:31 CDT 2024