2011-07-13 62 views
4

我有一个表BIG_TABLE,4万人次的纪录,他们是通过一个名为列集中在40组“process_type_cod” 。此列可能承担的值列表位于第二个表中。我们称之为small_table的Oracle SQL:如何选择N条记录每一个“组” /“簇”

所以,我们有一个big_table,其中有一个名为process_type_cod的NOT NULL FK,指向small_table(假设colum名称在两个表上都是相同的)。

我想要small_table的每个记录来自big_table的N记录(即10),

I.e. 来自big_table的10条记录与small_table的第一条记录相关 UNION 来自big_table的10条不同于小表的第二条记录的不同记录等等。

是否可以使用单个SQL函数获取?

+2

您关心您为每条记录获得哪10行?结果是否需要确定性? –

+0

不,没有必要。 – Revious

回答

9

我推荐一个分析函数,如rank()或row_number()。你可以用硬编码的工会做到这一点,但分析功能为你做了所有的辛苦工作。

select * 
from 
(
    select 
     bt.col_a, 
     bt.col_b, 
     bt.process_type_cod, 
     row_number() over (partition by process_type_cod order by col_a nulls last) rank 
    from small_table st 
    inner join big_table bt 
     on st.process_type_cod = bt.process_type_cod 
) 
where rank < 11 
; 

你甚至可能不需要这种联接,因为big_table具有你所关心的所有类型。在这种情况下,只需将'from子句'改为使用big_table并放弃连接即可。

这样做是执行查询,然后使用分区语句中的'order by'操作符对记录进行排序。对于给定组(这里我们按col_a分组),对每个记录连续应用数字行号(即1,2,3,4,5,n + 1 ...)。在外部where子句中,仅筛选数字小于N的记录。

+0

差不多。当col_a具有相同的值时,分析函数RANK将生成相同的数字,因此可以在此查询中为每个process_type_code选择多于10行。在这种情况下最好使用ROW_NUMBER。 –

+0

好的结果 - 我更新了答案。 –

+0

它是否在大桌子上打满桌子?是否有可能避免它?即我不需要排序,是否有空条目或类似的命令? – Revious