2009-05-01 52 views
1

我想對一個由數字索引的成員列表進行簡單查詢,並將它們分組爲等同大小的「桶」。因此,基本查詢是:將SQL結果分隔爲多個範圍

select my_members.member_index from my_members where my_members.active=1; 

說我得到1000成員索引號回來了,現在我想通過一個最大和最小成員索引,並分割成10個大小相等組。喜歡的東西:

在0活躍成員通過400:通過577 401 100個 活躍的會員:100 ......在1584 活躍成員通過1765:100

我能想出的最好的是反覆查詢最大(my_members.member_index)隨着越來越ROWNUM限制:

for r in 1 .. 10 loop 
    select max(my_members.member_index) 
    into ranges(r) 
    from my_members 
    where my_members.active = 1 
    and rownum < top_row 
    order by my_members.member_index asc; 
    top_row := top_row + 100; 
    end loop; 

回答

1

NTILE是要走的路 - 。值得在解析函數讀了,因爲他們能獲得巨大簡化您的SQL

原始代碼小評 - 做一個ROWNUM限制之前一個ORDER BY能產生不利的結果

for r in 1 .. 10 loop 
    select max(my_members.member_index) 
    into ranges(r) 
    from my_members 
    where my_members.active = 1 
    and rownum < top_row 
    order by my_members.member_index asc; 
    top_row := top_row + 100; 

端環;

嘗試以下方法:

create table example_nums (numval number) 

begin 
    for i in 1..100 loop 
     insert into example_nums values (i); 
    end loop; 
end; 

SELECT numval FROM example_nums 
WHERE rownum < 5 
ORDER BY numval DESC; 

爲了讓你期望你需要做的

SELECT numval FROM 
    (SELECT numval FROM example_nums 
    ORDER BY numval DESC) 
WHERE rownum < 5 

的結果(注 - 在幕後,甲骨文將翻譯成只有永遠保持「前4項的一個有效的排序這一點)。

0

看看在SQL CASE語句,並設置基於關閉您想要的範圍內的分組字段。

1

感謝您的幫助。過了好一會兒,以它的工作都變成一個聲明(適用於某些原因,也是一個目標),所以這裏就是我想出了,看起來像我的作品:

select max(member_index), ranger 
    from (SELECT member_index, 
        CASE 
         WHEN rownum < sized THEN 1 
         WHEN rownum < sized*2 THEN 2 
         WHEN rownum < sized*3 THEN 3 
         WHEN rownum < sized*4 THEN 4 
         WHEN rownum < sized*5 THEN 5 
         WHEN rownum < sized*6 THEN 6 
         WHEN rownum < sized*7 THEN 7 
         WHEN rownum < sized*8 THEN 8 
         WHEN rownum < sized*9 THEN 9 
         ELSE 10 
        END ranger 
      from my_members, 
        (select count(*)/10 sized 
         from my_members 
         where active = 1) 
      where active = 1 
      order by member_index) 
group by ranger; 

給我我的結果是這樣:

member_index ranger 
2297683  1 
2307055  2 
2325667  3 
2334819  4 
2343982  5 
2353325  6 
2362247  7 
6229146  8 
8189767  9 
26347329  10 
+1

幹得好。你已經改造了`NTILE`功能:) – 2010-06-29 23:42:08

2

它的簡單和更快的使用NTILE分析函數:

SELECT member_index, NTILE(10) OVER (ORDER BY member_index) FROM my_members; 

的Oracle 10g文檔:「NTILE是一個解析函數這將有序數據設置爲由expr指示的多個桶併爲每一行分配合適的桶編號。該桶通過expr的編號爲1「