按组随机选择一个行Oracle 10g

问题描述

这篇文章this thread相似,因为我每个小组有多个观察结果。但是,我只想随机选择其中的一个。我也在研究Oracle 10g。

person_id中每个df有多行。我想按person_iddbms_random.value()的每个组进行排序,然后从每个组中选择第一个观察值。为此,我尝试:

select
    person_id,purchase_date
from
    df
where
    row_number() over (partition by person_id order by dbms_random.value()) = 1

查询返回:

ORA-30483:此处不允许使用窗口功能 30483。00000-“此处不允许使用窗口功能” *原因:仅在查询的SELECT列表中允许使用窗口函数。而且,窗口函数不能作为另一个窗口或组函数的参数。

解决方法

使用子查询:

select person_id,purchase_date
from (select df.*,row_number() over (partition by person_id order by dbms_random.value()) as seqnum
      from df
     ) df
where seqnum = 1;
,

一种选择是使用WITH..AS条款:

WITH t AS
(
 SELECT df.*,ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY dbms_random.value()) AS rn    
   FROM df
)    
SELECT person_id,purchase_date
  FROM t
 WHERE rn = 1
 
,

集合查询(使用GROUP BY和集合函数)比做相同工作的等效分析函数要快得多。因此,如果要处理大量数据,或者数据不是太大,但必须经常运行此查询,则可能需要使用聚合而不是分析函数的更高效的查询。

这是一种可能的方法:

select person_id,max(purchase_date) keep (dense_rank first order by dbms_random.value()) 
           as random_purchase_date
from   df
group  by person_id
;