For example: My table has 10000 rows. First I will divide it in 5 sets of 2000(k) rows. Then from each set of 2000 rows I will select only top 100(n) rows. With this approach I am trying to scan some rows of table with a specific pattern.
Asked
Active
Viewed 367 times
0
-
3So what's the rule for splitting out the 2000 sets? – APC May 10 '17 at 07:40
-
there will be two parameters. Split size and scan size. There is no specific rule. It will depend on the no of rows in the table. – Raj May 10 '17 at 08:12
-
It would help to know what you are trying to achieve, the table structure relevant to the range splits and perhaps some sample data. This seems like a strange business requirement so some context might help. – BriteSponge May 10 '17 at 08:21
-
Sorry not to explain my problem statement correctly. @MT0 answer solved my problem. Thanks. – Raj May 10 '17 at 08:38
3 Answers
1
This solution uses the analytic ntile()
to split the raw data into five buckets. That result set is labelled using the analytic row_number()
which provides a filter to produce the final set:
with sq1 as ( select id, col1, ntile(5) over (order by id asc) as quintile
from t23
)
, sq2 as ( select id, col1, quintile
, row_number() over ( partition by quintile order by id asc) as rn
from sq1 )
select *
from sq2
where rn <= 200
order by quintile, rn
/

APC
- 144,005
- 19
- 170
- 281
1
Assuming you are ordering them 1 - 10000
using some logic and want to output only rows 1-100,2001-2100,4001-4100,etc
then you can use the ROWNUM
pseudocolumn:
SELECT *
FROM (
SELECT t.*,
ROWNUM AS rn -- Secondly, assign a row number to the ordered rows
FROM (
SELECT *
FROM your_table
ORDER BY your_condition -- First, order the data
) t
)
WHERE MOD( rn - 1, 2000 ) < 100; -- Finally, filter the top 100 per 2000.
Or you could use the ROW_NUMBER()
analytic function:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER ( ORDER BY your_condition ) AS rn
FROM your_table
)
WHERE MOD( rn - 1, 2000 ) < 100;
Is it possible to increase the set of sample data exponentially. Like 1k, 2k, 4k,8k....and then fetch some rows from these.
Replace the WHERE
clause with:
WHERE rn - POWER(
2,
TRUNC( CAST( LOG( 2, CEIL( rn / 1000 ) ) AS NUMBER(20,4) ) )
) * 1000 + 1000 <= 100

MT0
- 143,790
- 11
- 59
- 117
-
Just to add one more case in my problem. Is it possible to increase the set of sample data exponentially. Like 1k, 2k, 4k,8k....and then fetch some rows from these. – Raj May 10 '17 at 09:53
-
-1
use partition by and order by with row_number. it will look like following:
row_number()over(partition by partition_column order by order_column)<=100
partition_column will be your condition to divide set. order_column will be your condition to select top 100.

Bhavesh Ghodasara
- 1,981
- 2
- 15
- 29