2014-09-21 6 views
3

Я написал запрос, который дает n% из общего набора результатов. Я не уверен, является ли это эффективным способом запроса.Oracle - Limit Row_number() в процентах

Ниже мой запрос (его модифицированный один для понимания), который дает 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 
    ) 

Есть ли у вас какие-либо предложения, чтобы принять первый/последний/случайный п% от результата эффективно?

+0

В Oracle вы также можете использовать предложение 'sample (20)', чтобы получить 20% (случайные) строки оператора select. –

+0

Это не поможет ОП, так как он ищет упорядоченные строки. Мой прием - «NTILE» в 12c и предыдущих выпусках. В 12c теперь у нас есть новая строка ограничения строки, используя процент. –

ответ

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

+0

Спасибо @Sylvain за исправление URL –

+1

NTILE - это заклинатель! Спасибо большое. – Logan

+0

Да, это так. Немногие знают об этом :-) Хорошо, что теперь вы тоже это знаете. –

Смежные вопросы