Oracle选择与连接条件匹配的随机行

时间:2015-11-18 10:25:50

标签: oracle performance join random sample

我的目标很简单,只要部门在某个特定部门(比如2),我就必须创建一个临时表,其中包含来自员工表的一些随机值。对于其他部门,我不关心价值,可以是NULL

目前我有以下内容:

create table test 
as 
select s.DEPTNAME, 
        cast (
             (case when s.DEPTID in (2) then 
                (SELECT a.ENAME FROM 
                   (SELECT b.ENAME, b.DEPTID FROM EMPLOYEE b 
                    WHERE b.DEPTID IS NOT NULL 
                    ORDER BY DBMS_RANDOM.VALUE) a 
                  WHERE     a.DEPTID = s.DEPTID  AND ROWNUM = 1 
                )
               END)
              AS VARCHAR2(30)) "ENAME" from DEPARTMENT s;

但这里的主要问题与绩效有关。对于2中的每个部门值,我们都会使用一种EMPLOYEE表来获取单个随机ENAME。 有一个更好的方法吗 ?我知道样本可能有效,但我希望实现更多随机性。

1 个答案:

答案 0 :(得分:0)

第一个想法 - 加入随机编号的enames:

with 
  e as (select ename, deptid, row_number() over (order by dbms_random.value) rn 
          from employee where deptid = 2),
  c as (select count(1) cnt from e),
  d as (select deptname, deptid, round(dbms_random.value(1, c.cnt)) rn from department, c)
select d.deptname, e.ename from d left join e using (rn, deptid)

SQLFiddle demo

对我有用的第二个可能的解决方案是创建从表employee返回随机ename的函数 并在查询中使用它,但它可能会更慢。

修改 - 根据评论:

如果由于某种原因,您的陈述的第一部分是“固定的”,那么您可以使用以下语法:

create table test as 
select deptname, ename from (
  with
    e as (select ename, deptid, row_number() over (order by dbms_random.value) rn
            from employee where deptid = 2),
    c as (select count(1) cnt from e),
    d as (select deptname, deptid, round(dbms_random.value(1, c.cnt)) rn 
            from department cross join c)
  select d.deptname, e.ename from d left join e using (rn, deptid));