Oracle - 按百分比限制Row_number()

时间:2014-09-21 06:13:23

标签: sql oracle oracle11g

我编写了一个查询,它给出了总结果集中的n%。我不确定它是否是一种有效的查询方式。

以下是我的查询(它是一个用于理解的修改后的查询),它从总结果集中得出20%:

SELECT *
FROM (
    WITH RS AS (
            SELECT ID
                ,ROW_NUMBER() OVER (
                    ORDER BY ID
                    ) r_num
                ,count(1) OVER () AS n_rows
            FROM TAB1
            LEFT OUTER JOIN TAB2 ON TAB1.ID = TAB2.ID
            INNER JOIN TAB4 ON TAB4.ID = TAB4.ID
            INNER JOIN TAB3 ON TAB3.ID = TAB4.ID
            WHERE TAB2.ID_ IS NULL
                AND TAB3.C_ID = 'JP'
            )
    SELECT *
    FROM RS
    WHERE r_num <= round(n_rows * 0.2)
    ORDER BY ID
    )

您是否有任何建议以有效的方式从结果集中获取第一个/最后一个/随机n%?

1 个答案:

答案 0 :(得分:3)

由于您在11g(从标记看起来似乎),我建议使用NTILE分析函数。您可以在文档中阅读有关NTILE的更多信息。 NTILE会将有序数据集划分为多个存储桶。例如,在您的情况下,前10%的行将类似于:

NTILE (10) OVER (ORDER BY id)

可以将查询重写为:

WITH RS AS (
            SELECT ID
                ,NTILE (10) OVER (ORDER BY id) r_num
            FROM TAB1
            LEFT OUTER JOIN TAB2 ON TAB1.ID = TAB2.ID
            INNER JOIN TAB4 ON TAB4.ID = TAB4.ID
            INNER JOIN TAB3 ON TAB3.ID = TAB4.ID
            WHERE TAB2.ID_ IS NULL
                AND TAB3.C_ID = 'JP'
            )
SELECT id 
   FROM rs
  WHERE r_num = 10
ORDER BY id

注意:由于您没有提供测试用例,因此我没有表和数据来重新创建测试用例。

那是关于先前的12c,现在在12c你有新的ROW LIMITING CLAUSE,你需要将它添加到子句中:

FETCH FIRST 10 PERCENT ROWS ONLY

例如:

SELECT col
FROM   table
ORDER BY col
FETCH FIRST 10 PERCENT ROWS ONLY;

它优于旧的ROWNUM,这在预期的有序结果集时一直是个问题。使用12c中的新行限制子句,在上面的示例中,您将始终获得ORDERED结果集。您可以在此处查看更多示例ROW LIMITING clause