Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

How to convert RANGE_FROM to RANGE_TO to individual records

User_7JIQMSep 8 2022 — edited Sep 8 2022

I have a table that specifies a range of codes by two columns: range_from and range_to.
range_from range_to
1000 ............. 1003
What I want a query to do is list the individual codes in that range:
1000
1001
1002
1003
Picture provided to help with clarity:
image.png

Comments

Frank Kulash

Hi, User_7JIQM
Whenever you have a question, please post a little sample data (CREATE TABLE and INSERT statements for all tables involved, relevant columns only) so the people who want to help you can re-create the problem and test their ideas. Also post the exact results you want from that data, and explain why you want those results from that data. Always post your complete Oracle version (e.g. 18.4.0.0.0).
In this case, your sample data could be something like:

CREATE TABLE
sample_data (range_from, range_to)  AS
SELECT	   1000,	 1003  FROM dual UNION ALL
SELECT	   2000,	 2000	 FROM dual
;

If you want to get these results:

RANGE_FROM RANGE_TO     N
---------- -------- -----
      1000     1003  1000
      1000     1003  1001
      1000     1003  1002
      1000     1003  1003
      2000     2000  2000

from that sample data, then you can do it like this:

SELECT   *
FROM	 sample_data s
CROSS APPLY (
	        SELECT  s.range_from + LEVEL - 1 AS n
		FROM	dual
		CONNECT BY LEVEL <= 1 + s.range_to - s.range_from
   	  )     c
ORDER BY c.n
;
mathguy

Here's one way (using my own sample data, since I don't know how to use images in SQL Developer):

with
  tbl (id, range_from, range_to) as (
    select 1, 8, 9 from dual union all
    select 3, 5, 5 from dual union all
    select 9, 1, 5 from dual
  )
select id,  xmlcast(column_value as number) as branch
from   tbl, xmltable(range_from || ' to ' || range_to)
;

        ID     BRANCH
---------- ----------
         1          8
         1          9
         3          5
         9          1
         9          2
         9          3
         9          4
         9          5
Orcl Apex

@mathguy - Please elaborate on what you did above, I can not understand it.

Solomon Yakobson

XQUERY expression X to Y where X & Y are integers returns sequence of integers from X to Y.
SY.

mathguy

I used XML tools. Mostly a hack (using the tools in a problem that has nothing to do with XML), although I did use them in the way they were intended (which is generally not true for hacks).
A string like '1 to 3' is a valid XQuery expression, meaning pretty much what it says. 1 and 3 must be integers, and they don't need to be hard-coded - they can be replaced with any expressions that evaluate to integers. In your case, I used the values read from your existing table.
XMLTable evaluates it and decomposes it into its elements, in the form of a table with a single column, one row per element. As in all table function cases, the elements returned by XMLTable are in a column named COLUMN_VALUE.
Note though that the elements (the row values) are XML values, not plain numbers. In some database interfaces (like SQL*Plus), the values may be shown as numbers (1, 2, 3) but in fact they are not; if you try to add them together, for example, you will get an error. XMLCast takes these elements and casts them as number - that's how we get the numbers in the end.
If this explanation raises more questions than it answers, it is possible that you are not familiar with XML in general. If that is the case: If you need to use XML in your other work, then you need to learn about XML (and the trick I used here is definitely not the way to learn XML!). If you don't need to use XML other than for silly tricks like the one I used, then you can just play with it a bit, get comfortable with it, use it when you need to, and move on to other tasks.

1 - 5

Post Details

Added on Sep 8 2022
5 comments
356 views