Oracle: query or procedure to traverse table - recursion

I have a table made in this way:
COLUMN_A
COLUMN_B
COLUMN_C
35108337
B0110555
35108337
E15627104
35108338
E15627104
800384
L0309599
18181
800384
E1359191
800385
B0110556
800385
E1359191
1030137
L0309597
18181
1030137
E1458050
1030138
B0110556
1030138
E1458050
2042225
B0110555
2042225
E1896214
2042227
B0110555
2042227
E1896215
2055249
B0110555
2055249
E292177
2055250
B0110556
2055250
E1900966
2055251
E1900966
2055251
E292177
25908098
E1896215
25908099
E1896214
and I need to navigate it through column_a and column_b. I know the starting point, which is COLUMN_A with value '35108338'. Once I got starting point, I need to check value of COLUMN_B, look for this value in COLUMN_B and take COLUMN_A, look value and look for it in COLUMN_A (which not already taken), until I will reach a record with COLUMN_C not NULL.
For example, staring from '35108338', I will have:
COLUMN_A: 35108338 COLUMN_B: E15627104
COLUMN_A: 35108337 COLUMN_B: E15627104
COLUMN_A: 35108337 COLUMN_B: B0110555
COLUMN_A: 2055249 COLUMN_B: B0110555
COLUMN_A: 2055249 COLUMN_B: E292177
COLUMN_A: 2055251 COLUMN_B: E292177
COLUMN_A: 2055251 COLUMN_B: E1900966
COLUMN_A: 2055250 COLUMN_B: E1900966
COLUMN_A: 2055250 COLUMN_B: B0110556
COLUMN_A: 1030138 COLUMN_B: B0110556
COLUMN_A: 1030138 COLUMN_B: E1458050
COLUMN_A: 1030137 COLUMN_B: E1458050
COLUMN_A: 1030137 COLUMN_B: L0309597
I may never reach a record with a column_c not null
I may have multiple roads to do. For example B0110555 is repeating 4 times, so there's more than one road.
I tried with a stored procedure, to make a bulk collect of these data and to manage it with arrays, but I have problem when multiple roads.

You can use a hierarchical query and alternate matching on column_a and column_b:
SELECT t.*,
LEVEL,
SYS_CONNECT_BY_PATH(
CASE MOD(LEVEL, 2)
WHEN 1
THEN TO_CHAR(column_a)
ELSE column_b
END,
'->'
) AS path
FROM table_name t
START WITH column_a = 35108338
CONNECT BY NOCYCLE
(MOD(LEVEL, 2) = 0 AND PRIOR column_b = column_b)
OR (MOD(LEVEL, 2) = 1 AND PRIOR column_a = column_a)
ORDER SIBLINGS BY column_a, column_b
Which, for the sample data:
CREATE TABLE table_name (COLUMN_A, COLUMN_B, COLUMN_C) AS
SELECT 35108337, 'B0110555', NULL FROM DUAL UNION ALL
SELECT 35108337, 'E15627104', NULL FROM DUAL UNION ALL
SELECT 35108338, 'E15627104', NULL FROM DUAL UNION ALL
SELECT 800384, 'L0309599', 18181 FROM DUAL UNION ALL
SELECT 800384, 'E1359191', NULL FROM DUAL UNION ALL
SELECT 800385, 'B0110556', NULL FROM DUAL UNION ALL
SELECT 800385, 'E1359191', NULL FROM DUAL UNION ALL
SELECT 1030137, 'L0309597', 18181 FROM DUAL UNION ALL
SELECT 1030137, 'E1458050', NULL FROM DUAL UNION ALL
SELECT 1030138, 'B0110556', NULL FROM DUAL UNION ALL
SELECT 1030138, 'E1458050', NULL FROM DUAL UNION ALL
SELECT 2042225, 'B0110555', NULL FROM DUAL UNION ALL
SELECT 2042225, 'E1896214', NULL FROM DUAL UNION ALL
SELECT 2042227, 'B0110555', NULL FROM DUAL UNION ALL
SELECT 2042227, 'E1896215', NULL FROM DUAL UNION ALL
SELECT 2055249, 'B0110555', NULL FROM DUAL UNION ALL
SELECT 2055249, 'E292177', NULL FROM DUAL UNION ALL
SELECT 2055250, 'B0110556', NULL FROM DUAL UNION ALL
SELECT 2055250, 'E1900966', NULL FROM DUAL UNION ALL
SELECT 2055251, 'E1900966', NULL FROM DUAL UNION ALL
SELECT 2055251, 'E292177', NULL FROM DUAL UNION ALL
SELECT 25908098, 'E1896215', NULL FROM DUAL UNION ALL
SELECT 25908099, 'E1896214', NULL FROM DUAL;
Outputs:
COLUMN_A
COLUMN_B
COLUMN_C
LEVEL
PATH
35108338
E15627104
null
1
->35108338
35108337
E15627104
null
2
->35108338->E15627104
35108337
B0110555
null
3
->35108338->E15627104->35108337
2042225
B0110555
null
4
->35108338->E15627104->35108337->B0110555
2042225
E1896214
null
5
->35108338->E15627104->35108337->B0110555->2042225
25908099
E1896214
null
6
->35108338->E15627104->35108337->B0110555->2042225->E1896214
2042227
B0110555
null
4
->35108338->E15627104->35108337->B0110555
2042227
E1896215
null
5
->35108338->E15627104->35108337->B0110555->2042227
25908098
E1896215
null
6
->35108338->E15627104->35108337->B0110555->2042227->E1896215
2055249
B0110555
null
4
->35108338->E15627104->35108337->B0110555
2055249
E292177
null
5
->35108338->E15627104->35108337->B0110555->2055249
2055251
E292177
null
6
->35108338->E15627104->35108337->B0110555->2055249->E292177
2055251
E1900966
null
7
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251
2055250
E1900966
null
8
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966
2055250
B0110556
null
9
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250
800385
B0110556
null
10
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556
800385
E1359191
null
11
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556->800385
800384
E1359191
null
12
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556->800385->E1359191
800384
L0309599
18181
13
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556->800385->E1359191->800384
1030138
B0110556
null
10
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556
1030138
E1458050
null
11
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556->1030138
1030137
E1458050
null
12
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556->1030138->E1458050
1030137
L0309597
18181
13
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556->1030138->E1458050->1030137
If you just want to find the non-null column_c values then add a WHERE clause:
...
FROM table_name t
WHERE column_c IS NOT NULL
START WITH column_a = 35108338
...
Which outputs:
COLUMN_A
COLUMN_B
COLUMN_C
LEVEL
PATH
800384
L0309599
18181
13
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556->800385->E1359191->800384
1030137
L0309597
18181
13
->35108338->E15627104->35108337->B0110555->2055249->E292177->2055251->E1900966->2055250->B0110556->1030138->E1458050->1030137
fiddle

Related

Oracle left join with Union gives duplicate records

Have two tables payment, payment_info , trying with left join and union to get the ordnums, it gives me duplicate records, below is my tables data structure.
Payment Table:
id
invoice
cardpay
gpay
phonepe
1
4567
0000123
null
null
2
4567
null
dummy#dummy
null
3
4567
null
null
P#dummy
4
4568
0000124
null
null
Payment_info Table:
ordnum
payment_method
payment_value
101
C
0000123
102
G
dummy#dummy
103
C
0000124
Query:
select pinfo.ordnum from
payment p
left join payment_info pinfo
on (select payment_info.ordnum
from payment_info
where payment_info.payment_method = 'C'
and payment_info.payment_value = p.cardpay
union
select payment_info.ordnum
from payment_info
where payment_info.payment_method = 'G'
and payment_info.payment_value = p.gpay
union
select payment_info.ordnum
from payment_info
where payment_info.payment_method = 'P'
and payment_info.payment_value = p.phonepe ) = pinfo.ordnum
where p.invoice = '4567'
Result: It gives 3 duplicate records.
ordnum
101
101
101
Expected result value is : 101,102, null
Can you please explain me on why it is generating duplicate records, also please let me know how can I solve this, it works good with "OR", but that would cause performance issue, any other solution that that would be really helpful.
Also in sql server it works good.
How about something simpler?
Sample data:
SQL> with
2 payment (id, invoice, cardpay, gpay, phonepe) as
3 (select 1, 4567, '0000123', null , null from dual union all
4 select 2, 4567, null , 'dummy#dummy', null from dual union all
5 select 3, 4567, null , null , 'P#dummy' from dual union all
6 select 4, 4568, '0000124', null , null from dual
7 ),
8 payment_info (ordnum, payment_method, payment_value) as
9 (select 101, 'C', '0000123' from dual union all
10 select 102, 'G', 'dummy#dummy' from dual union all
11 select 103, 'C', '0000124' from dual
12 )
Query begins here: outer join it is, but simplified as coalesce returns the first non-null value. This should be OK because there can be only one payment "method" (cardpay, gpay or phonepe) per ID.
13 select p.id, i.ordnum
14 from payment p left join payment_info i on
15 coalesce(p.cardpay, p.gpay, p.phonepe) = i.payment_value
16 where p.invoice = 4567;
ID ORDNUM
---------- ----------
1 101
2 102
3
SQL>
You can use a single LEFT OUTER JOIN:
SELECT i.ordnum
FROM payment p
LEFT OUTER JOIN payment_info i
ON ( (i.payment_method, i.payment_value) IN (
('C', p.cardpay),
('G', p.gpay),
('P', p.phonepe)
) )
WHERE p.invoice = 4567;
or:
SELECT i.ordnum
FROM payment p
LEFT OUTER JOIN payment_info i
ON ( (i.payment_method = 'C' AND i.payment_value = p.cardpay)
OR (i.payment_method = 'G' AND i.payment_value = p.gpay)
OR (i.payment_method = 'P' AND i.payment_value = p.phonepe)
)
WHERE p.invoice = 4567;
Which, for the sample data:
CREATE TABLE payment (id, invoice, cardpay, gpay, phonepe) AS
SELECT 1, 4567, '0000123', NULL , NULL FROM DUAL UNION ALL
SELECT 2, 4567, NULL , 'dummy#dummy', NULL FROM DUAL UNION ALL
SELECT 3, 4567, NULL , NULL , 'P#dummy' FROM DUAL UNION ALL
SELECT 4, 4568, '0000124', NULL , NULL FROM DUAL;
CREATE TABLE payment_info (ordnum, payment_method, payment_value) AS
SELECT 101, 'C', '0000123' FROM DUAL UNION ALL
SELECT 102, 'G', 'dummy#dummy' FROM DUAL UNION ALL
SELECT 103, 'C', '0000124' FROM DUAL;
Both output:
ORDNUM
101
102
null
fiddle

Always return all row, even when query has no result

I have a "tt_Results" table which contains exactly three row / ID like:
ID | ResultType
---------------
1 | first
1 | second
1 | third
My query looks like:
select t.resultType
from tt_Results
where ID = 1;
Normally, this query should return all the three row. My problem is if one or more row not exist I must union all the three "type".
select res.* from
(
select resultType, '1' as exists
from tt_Results
where ID = 1
union all
select 'first' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'first' and ID = 1)
union all
select 'second' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'second' and ID = 1)
union all
select 'third' resulttype, '0' as exists
from dual
where not exists (
select resulttype
from tt_Results
where resulttype = 'third' and ID = 1)
) res
The final query result looks good but it is very slow. Anyone have a better PL/SQL solution for it? Thanks for the answers!
Left join to your table from a table of all types, using a case to calculate exists based on whether a join was made or not:
select
type,
case when resultType is null then '0' else '1' end as exists
from (select 'first' type from dual union
select 'second' from dual union
select 'third' from dual) t
left join tt_Results on resultType = type
and ID = 1
Note that the condition ID = 1 is part of the join condition, not in a where clause.
I recommend creating a 3-row table for the types, then the query would become simply:
select
type,
case when resultType is null then '0' else '1' end as exists
from types
left join tt_Results on resultType = type
and ID = 1
You can do this by creating a subquery to hold the result types you're interested in, and then using a partitioned outer join, like so:
with tt_results as (select 1 id, 'first' resulttype from dual union all
select 1 id, 'second' resulttype from dual union all
select 1 id, 'third' resulttype from dual union all
select 2 id, 'second' resulttype from dual union all
select 2 id, 'third' resulttype from dual union all
select 3 id, 'first' resulttype from dual),
dummy as (select 1 position, 'first' resulttype from dual union all
select 2 position, 'second' resulttype from dual union all
select 3 position, 'third' resulttype from dual)
select res.id,
d.resulttype,
case when res.resulttype is not null then 1 else 0 end res_exists
from dummy d
left outer join tt_results res partition by (res.id) on d.resulttype = res.resulttype
order by res.id,
d.position;
ID RESULTTYPE RES_EXISTS
---------- ---------- ----------
1 first 1
1 second 1
1 third 1
2 first 0
2 second 1
2 third 1
3 first 1
3 second 0
3 third 0
Adrian Billington has produced an excellent article on partititioned outer joins if you want to learn more about them.
If your tt_results table could contain more resulttypes than you're interested in, you might want/need to add a predicate to only grab the rows from the dummy subquery, otherwise you could get ids where all 3 resulttypes don't exist (although that may be what you want to see).
ETA: This will work if you need to select multiple ids in one go.

how to join all the tables without using any condition

all the below results are not related to each other wheras we cannot use any condition.
ID
----------
1
2
3
4
5
6
7
7 rows selected.
NAME
-----------------
SRUJAN
DEERAJ
VINEETH
CHANIKYA
LAVANYA
KAVITHA
BUNNY
7 rows selected.
AGE
----------
23
24
26
25
29
28
24
7 rows selected.
ADDRESS
-------------
NAGARAM
BANDLAGUDA
UPPAL
KUKATPALLY
HB COLONY
MOULALI
BOUDHA NAGAR
7 rows selected.
SALARY
----------
12000
13000
14000
15000
16000
17000
18000
7 rows selected.
I USED
SQL>select id,name,age,address,salary from table1,table2,table3,table4,table5;
but it showing 16807 rows selected
i want to get only one table.
please suggest a query.
The only possible join between 2 tables having only 1 columns and both having no relation is cross join. You cannot avoid it. And the same you are getting when you tried to join. The best way for you is to create a sequence as ID and then call it in your select statement of table2.
CREATE SEQUENCE TEST_SEQ
START WITH 1
MAXVALUE 9999999999999999999999999999
MINVALUE 1
NOCYCLE;
select TEST_SEQ.nextval ID,col1 NAME
from table2;
Here is one way, using inner joins. This solution matches the lowest id with the first name in alphabetical order, the lowest age, etc.
If instead of this ordered matching you need random matching, that is easy to do as well: in the over... clause of the prep tables, change the order by clause to order by dbms_random.value() (in all places).
In the solution below I use only the first three tables, but the same works for any number of input tables.
with
tbl_id ( id ) as (
select 1 from dual union all
select 2 from dual union all
select 3 from dual union all
select 4 from dual union all
select 5 from dual union all
select 6 from dual union all
select 7 from dual
),
tbl_name ( name ) as (
select 'SRUJAN' from dual union all
select 'DEERAJ' from dual union all
select 'VINEETH' from dual union all
select 'CHANIKYA' from dual union all
select 'LAVANYA' from dual union all
select 'KAVITHA' from dual union all
select 'BUNNY' from dual
),
tbl_age ( age ) as (
select 23 from dual union all
select 24 from dual union all
select 26 from dual union all
select 25 from dual union all
select 29 from dual union all
select 28 from dual union all
select 24 from dual
),
prep_id ( id, rn ) as (
select id, row_number() over (order by id) from tbl_id
),
prep_name ( name, rn ) as (
select name, row_number() over (order by name) from tbl_name
),
prep_age ( age , rn ) as (
select age, row_number() over (order by age) from tbl_age
)
select i.id, n.name, a.age
from prep_id i inner join prep_name n on i.rn = n.rn
inner join prep_age a on i.rn = a.rn
;
Output:
ID NAME AGE
---------- -------- ----------
1 BUNNY 23
2 CHANIKYA 24
3 DEERAJ 24
4 KAVITHA 25
5 LAVANYA 26
6 SRUJAN 28
7 VINEETH 29
7 rows selected

SQLITE : near from syntax error:

I stucked on following error if i'm executing this SQLlite command:
Error: near "FROM": syntax error
I check code of the query few times but i cannot able to locate error.
Could somebody tell me what is wrong in my code?
Thanks for any help.
SQL query:
SELECT d.date AS DATE,
IFNULL(DIALS_CNT, 0) AS DIALS_CNT,
IFNULL(APPT_CNT, 0) AS APPT_CNT,
IFNULL(CONVERS_CNT, 0) AS CONVERS_CNT,
FROM
(SELECT DATE('2014-01-01', '+' || (t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) || ' days') date
FROM
(SELECT 0 i
UNION SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7
UNION SELECT 8
UNION SELECT 9) t0,
(SELECT 0 i
UNION SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7
UNION SELECT 8
UNION SELECT 9) t1,
(SELECT 0 i
UNION SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7
UNION SELECT 8
UNION SELECT 9) t2,
(SELECT 0 i
UNION SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7
UNION SELECT 8
UNION SELECT 9) t3,
(SELECT 0 i
UNION SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7
UNION SELECT 8
UNION SELECT 9) t4) d
LEFT JOIN
(SELECT substr(m.date, 1, 10) AS my_date,
COUNT(m.ID) AS 'DIALS_CNT',
(SELECT COUNT(*)
FROM dialed_calls subq
WHERE subq.call_result = 'APPT'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) AS 'APPT',
(SELECT COUNT(*)
FROM dialed_calls subq
WHERE subq.call_result = 'CONV_NO_APPT'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) AS 'CONV_NO_APPT',
(SELECT COUNT(*)
FROM dialed_calls subq
WHERE subq.call_result = 'CANNOT_REACH'
AND substr(m.date, 1, 10) = substr(subq.DATE, 1, 10)) AS 'CANNOT_REACH'
FROM dialed_calls m
GROUP BY my_date) t ON d.date = t.my_date
WHERE d.date BETWEEN '2014-09-30' AND '2014-09-20'
ORDER BY d.date;
A simple typo;
IFNULL(CONVERS_CNT, 0) AS CONVERS_CNT, <-- extraneous comma
FROM

Select numbers between a range (1 to 100) in sqlite

I know some of the solutions in SQL but couldn't find any of them from SQlite.
I just want to execute a select query that returns a resultset of numbers ranging from 1 to 100.
Numbers
1
2
3
4
......
5
A correction: I don't actually have a table at all. (however a solution is encouraged with a virtual table like dual in MySQL)
Thanks sgmentzer!
Inspired by your answer I went ahead and also found this:
WITH RECURSIVE
cnt(x) AS (
SELECT 1
UNION ALL
SELECT x+1 FROM cnt
LIMIT 100000
)
SELECT x FROM cnt;
How about
SELECT * FROM myTable WHERE myNumber >= 1 AND myNumber <= 100;
?
Example subquery to generate the series 1 <= n <= 100000 in SQLite. No table is created or used.
select 1+e+d*10+c*100+b*1000+a*10000 as n from
(select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9),
(select 0 as b union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9),
(select 0 as c union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9),
(select 0 as d union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9),
(select 0 as e union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9);
I don't think SQLite has a clean way to do this, so you'll need to use a virtual table interface. SQLite ships one for 'C', and apsw has one for python as I'll demonstrate below. Here's documentation for the APSW Virtual Table interface.
#!/usr/bin/python
import apsw,tempfile
### Opening/creating database
filename=tempfile.mktemp() #insecure - do not use in production code
connection=apsw.Connection(filename)
cursor=connection.cursor()
# This gets registered with the Connection
class Source:
def Create(self, db, modulename, dbname, tablename, *args):
schema="create table foo( dummy integer )"
return schema,Table()
Connect=Create
# Represents a table
class Table:
def __init__(self):
pass
def BestIndex(self, constraints, orderbys):
used = []
self.constraints = []
ucount = 0
for c in constraints:
if c[1] in (
apsw.SQLITE_INDEX_CONSTRAINT_GT,
apsw.SQLITE_INDEX_CONSTRAINT_GE,
apsw.SQLITE_INDEX_CONSTRAINT_LT,
apsw.SQLITE_INDEX_CONSTRAINT_LE,
apsw.SQLITE_INDEX_CONSTRAINT_EQ,
):
used.append( ucount ) #tell sqlite we want to use this one
self.constraints.append( c[1] ) #save some for later
else:
used.append( None ) #skip anything we don't understand
ucount += 1
return ( used, # used constraints list
0, # index number - no biggie we only support one right now
)
def Open(self):
return Cursor(self)
def Disconnect(self):
pass
Destroy=Disconnect
# Represents a cursor
class Cursor:
def __init__(self, table):
self.table=table
def Filter(self, indexnum, indexname, constraintargs):
start = 0
self.end = 4000000000
#map constraint arguments to start and end of generation
for tc, ca in zip( self.table.constraints, constraintargs ):
if tc == apsw.SQLITE_INDEX_CONSTRAINT_EQ:
start = ca
self.end = ca
elif tc == apsw.SQLITE_INDEX_CONSTRAINT_LE:
if self.end > ca:
self.end = ca
elif tc == apsw.SQLITE_INDEX_CONSTRAINT_LT:
if self.end >= ca:
self.end = ca
elif tc == apsw.SQLITE_INDEX_CONSTRAINT_GE:
if start < ca:
start = ca
elif tc == apsw.SQLITE_INDEX_CONSTRAINT_GT:
if start >= ca:
start = ca
self.pos = start
def Eof(self):
return self.pos > self.end
def Rowid(self):
return self.pos
def Next(self):
self.pos+=1
def Close(self):
pass
# Register the module as intsource, you can make a bunch if needed
connection.createmodule("intsource", Source())
# Create virtual table to use intsource
cursor.execute("create virtual table uints using intsource()")
# Do some counting
for i in cursor.execute("SELECT rowid FROM uints WHERE rowid BETWEEN 1 AND 100"):
print i
This implements a virtual-table type named "intsource", which by default counts from 0 to 4*10^9. It supports directly filtering by equality and comparison, but any other constraints will still be filtered out by sqlite. Virtual tables are a very powerful concept you can do a lot with, this is probably one of the simplest uses for them. Also, thank you for a good excuse to try out a new virtual table API.
SELECT * FROM Numbers limit 1, 100;
If your goal is to select actual records from a table with values between 1 and 100, use BETWEEN as shown by the other respondents.
If your goal is to generate a sequence of numbers from 1 to 100 without having a table to base it on, I don't believe SQLite has a feature that does this.
SELECT * FROM myTable WHERE myNumber BETWEEN 1 AND 100;
This is more efficient than using 2 WHERE clauses.

Resources