【问题标题】:Oracle select random rows matching a join conditionOracle 选择与连接条件匹配的随机行
【发布时间】:2016-02-20 00:54:23
【问题描述】:

我的目标很简单,只要部门位于某个特定部门(例如 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。 有一个更好的方法吗 ?我知道样本可能有效,但我想获得更多的随机性。

【问题讨论】:

  • 您为什么将CAST ENAME 作为数字?这不应该是某种员工姓名吗?
  • 对不起,你是对的,它的 CAST AS VARCHAR2(30)
  • 您的查询可能会多次返回同一员工。这是故意的吗?还是您宁愿每个员工最多一次?
  • 员工姓名重复是可以的。但它必须是随机的。

标签: oracle performance join random sample


【解决方案1】:

第一个想法 - 加入随机编号的名​​称:

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

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


编辑 - 根据评论:

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

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));

【讨论】:

  • 您好,非常感谢您的解决方案。它绝对有效。如果我通过说我的 部分是固定的并且我必须编写一个 sql 查询以在部门为 2 时从员工表中获取随机 ename 来陈述不同的问题,内部 SQL 查询将如何将是 ?基本上我想每次都为部门表调用我的 sql 查询。我们可以在没有函数的情况下写这个吗?
猜你喜欢
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
相关资源
最近更新 更多