Skip to Main Content
  • Questions
  • select from table based on ratio stored in second table

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Mike.

Asked: May 07, 2016 - 7:40 am UTC

Last updated: May 09, 2016 - 8:30 am UTC

Version: 11.2.0.4

Viewed 1000+ times

You Asked

Hey,

I would need a query which fetches x rows based on a ratio in a field of a second table.
So I have two tables, TABLE_X and TABLE_Y, TABLE_X holds 3 or more rows:

name ratio
A 1
B 1
C 2

TABLE_Y has n rows with each row matching the name of TABLE_X:

test1 test2 name test3
test1 test2 A test3
test1 test2 A test3
test1 test2 A test3
test1 test2 B test3
test1 test2 B test3
test1 test2 B test3
test1 test2 B test3
test1 test2 C test3
test1 test2 C test3
test1 test2 C test3
test1 test2 C test3
test1 test2 C test3
test1 test2 C test3

so in this case I have a ratio of 1:1:2, C has 6 rows so I am allowed to fetch 3 A and 3 B. Now I need a query which allows me to fetch based on the ratio provided by TABLE_X.

Do you have any suggestions?

and Chris said...

So, by "return the ratio", I'm assuming you mean:

- Scale up the ratio column in table_x based on the number of rows in table_y

If so, you can do this by:

- Summing the ratios in table_x
- Counting the rows in table_y
- Dividing the results of count / sum
- Return the number of rows for each name < this multiplied by the ratio

You can use analytic functions to do the sum, count and assign the row number:

create table table_x (
  name  varchar2(1),
  ratio int
);

insert into table_x values ('A', 1);
insert into table_x values ('B', 1);
insert into table_x values ('C', 2);

create table table_y (
  name varchar2(1)
);

insert into table_y values ('A');
insert into table_y values ('A');
insert into table_y values ('A');
insert into table_y values ('B');
insert into table_y values ('B');
insert into table_y values ('B');
insert into table_y values ('B');
insert into table_y values ('C');
insert into table_y values ('C');
insert into table_y values ('C');
insert into table_y values ('C');
insert into table_y values ('C');
insert into table_y values ('C');

with r1 as (
  select table_x.*, 
         sum(ratio) over () sm
  from   table_x
), r2 as ( 
  select table_y.*, 
         count(*) over () ct,
         row_number() over (partition by name order by name) rn
  from   table_y
)
  select r2.name, r2.rn
  from   r1
  join   r2
  on     r1.name = r2.name
  where  (r2.ct/r1.sm * ratio) > rn;

N         RN
- ----------
A          1
A          2
A          3
B          1
B          2
B          3
C          1
C          2
C          3
C          4
C          5
C          6

 12 rows selected 


Is this answer out of date? If it is, please let us know via a Comment

More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.