Sql 任意分布的排序结果
我的数据库中有几千个作业,它们的列的值为“active”或“inactive”。大约5%的工作是“不活跃的”。每天都会增加工作岗位(以百为单位)。当现有作业标记为“非活动”时,我们将保持准确率(如果“非活动”作业太多,则删除) 我需要对所有作业进行排序,使“非活动”作业均匀分布。最理想的情况是,每20个“活动”作业中就有一个是“非活动”作业(结果按20分页) 我怎样才能做到这一点?数据库是PostgresqlSql 任意分布的排序结果,sql,postgresql,Sql,Postgresql,我的数据库中有几千个作业,它们的列的值为“active”或“inactive”。大约5%的工作是“不活跃的”。每天都会增加工作岗位(以百为单位)。当现有作业标记为“非活动”时,我们将保持准确率(如果“非活动”作业太多,则删除) 我需要对所有作业进行排序,使“非活动”作业均匀分布。最理想的情况是,每20个“活动”作业中就有一个是“非活动”作业(结果按20分页) 我怎样才能做到这一点?数据库是Postgresql drop sequence rownum1 ; create temp sequenc
drop sequence rownum1 ;
create temp sequence rownum1;
drop sequence rownum2 ;
create temp sequence rownum2;
select * from(
select job_name, rownum1*20 as myorder from jobs where job_status =0
union
select job_name, rownum2 as myorder from jobs where job_status =1
)
order by myorder desc
如果非活动作业与活动作业的比例为1到20,此查询将使它们均匀分布。如果您的比率超过此最佳比率,则在查询的顶部将有许多非活动作业。
每次运行此查询时都需要删除并重新创建rownums序列我同意kurast的一般方法,但有两点可能会有所帮助:
分享和享受。我会为此尝试一个用户定义的功能
create table jobs (
id serial primary key,
job_status smallint not null default 1,
job_name text default 'FIXME',
inserted timestamptz default now()
);
insert into jobs ( job_status,inserted )
select case when random()<=0.05 then 0 else 1 end, localtimestamp
from generate_series(1,1000) x(x);
create or replace function get_jobs(p_limit int,p_offset int)
returns setof jobs as $$
declare
v_limit1 integer;
v_offset2 integer;
rec record;
begin
v_limit1 := p_limit - 1;
v_offset2 := p_offset / 20;
for rec in select * from jobs where job_status=1
order by inserted desc limit v_limit1 offset p_offset
loop
return next rec;
end loop;
return query select * from jobs where job_status=0 offset v_offset2 limit 1;
return;
end;
$$ language plpgsql;
你应该测试所有答案,并标出一个答案
create table jobs (
id serial primary key,
job_status smallint not null default 1,
job_name text default 'FIXME',
inserted timestamptz default now()
);
insert into jobs ( job_status,inserted )
select case when random()<=0.05 then 0 else 1 end, localtimestamp
from generate_series(1,1000) x(x);
create or replace function get_jobs(p_limit int,p_offset int)
returns setof jobs as $$
declare
v_limit1 integer;
v_offset2 integer;
rec record;
begin
v_limit1 := p_limit - 1;
v_offset2 := p_offset / 20;
for rec in select * from jobs where job_status=1
order by inserted desc limit v_limit1 offset p_offset
loop
return next rec;
end loop;
return query select * from jobs where job_status=0 offset v_offset2 limit 1;
return;
end;
$$ language plpgsql;
select * from(
select *, nextval('rownum1')*20 as myorder from jobs where job_status =0
union
select *, nextval('rownum2') as myorder from jobs where job_status =1
) subq
order by myorder desc;