0

I have table with below data :

Block_id Value

1             5
2             5
3             5
4             0
5             0
6             4
7             4

And I have to write query that give me below output :

Block_id

   1-3
   6-7

How to achieve this with pl/sql in Oracle 11g ?

4
  • 3
    Why should the first column contain the values from 1 to 5? Please explain the logic behind your query more Commented Feb 27, 2013 at 10:26
  • Opssssssss...... sory sory . its my miskate .. It should 3 insted of 5 Commented Feb 27, 2013 at 10:28
  • Can the table contain separate ranges having the same Value? I.e., in your above example, are additional tuples (8/5, 9/5, ...) possible? Commented Feb 27, 2013 at 10:47
  • yes it is possible . 8/4, 9/5 is also possible .. Means i need only those continouse block id range for which value is not 0 Commented Feb 27, 2013 at 11:09

3 Answers 3

1

you can do something like:

SQL> select * from data order by block_id;

  BLOCK_ID      VALUE
---------- ----------
         1          5
         2          5
         3          5
         4          0
         5          0
         6          4
         7          4
         9          5
        10          5
        12          2

SQL> select min(block_id) || '-' || max(block_id) block_range, value
  2    from (select block_id, value, max(grp) over (partition by value order by block_id) grp
  3            from (select block_id, value,
  4                         case
  5                           when lag(block_id) over (partition by value order by block_id) < block_id - 1
  6                           then
  7                             row_number() over (partition by value order by block_id)
  8                           when row_number() over (partition by value order by block_id) = 1 then 1
  9                           else null
 10                         end grp
 11                    from data
 12                   where value != 0))
 13   group by value, grp
 14   order by min(block_id);

BLOCK_RANG      VALUE
---------- ----------
1-3                 5
6-7                 4
9-10                5
12-12               2
Sign up to request clarification or add additional context in comments.

1 Comment

Wow. u genious.......... this not exactly i wana .. but i can make changes in this and achieve my requirement.... Thanks DAZZAL
0

You do not need PL/SQL to do this, a simple query will do:

CREATE TABLE test(
    a   INTEGER,
    b   INTEGER
);

INSERT INTO test VALUES (1, 5);
INSERT INTO test VALUES (2, 5);
INSERT INTO test VALUES (3, 5);
INSERT INTO test VALUES (4, 0);
INSERT INTO test VALUES (5, 0);
INSERT INTO test VALUES (6, 4);
INSERT INTO test VALUES (7, 4);

select min(a) || '-' || max(a) from test group by b order by 1;

Comments

0

An alternative approach is to use aggregate functions:

select distinct
        min(block_id) over (partition by value) || '-' ||
        max(block_id) over (partition by value)
   from whatever_your_table_is_called
   where value > 0;

2 Comments

No it will not work ... because it include range having value as '0' which is not corre t
Thanks for your answer but i am not looking for partition by . If For block id 6 and 7 value are different and not 0 then it also shows as 6-7 . It mean i need that continueous block id range for which value is not 0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.