2012-01-04 1 views
2

Мне пришлось копировать данные из таблиц oracle в файлы.ROW_NUMBER() неправильно упорядочивает записи

У меня есть запрос соединения, который извлекает записи 800k, поэтому я использовал функцию row_number() вместе с предложением order by, чтобы генерировать 4 файла, содержащих по 200 тыс. Каждый.

Запрос:

SELECT * FROM (
    SELECT ROW_NUMBER() OVER (order by FILE_KEY desc) rn, 
     FILE_KEY, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO 
    FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
    WHERE loc.CATALOG_NO = rout.FILE_KEY) 
WHERE rn BETWEEN start AND end; 

Параметры:

For 1st File : start =1 ,end = 200000 
For 2nd File : start =200001 ,end = 400000 
For 3rd File : start =400001 ,end = 600000 
For 4th File : start =600001 ,end = 800000 

Но когда я проверил последний 10 строку, используя этот запрос в браузере SQL запросов и последние 10 строк файла различны, что является последовательность отличается файл и SQL-запрос.

SELECT * FROM (
    SELECT ROW_NUMBER() OVER( order by FILE_KEY desc) rn, 
     FILE_KEY,ROUTING_NO,INTLROUT_TYPE,ABBR_COUNTRY_CODE_2D,HO_CATALOG_NO 
    FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
    WHERE loc.CATALOG_NO=rout.FILE_KEY) 
WHERE rn BETWEEN 709990 AND 80000; 
+0

Какая таблица является мастером, а какие детали? Если BANK_INTL_LOC_TBL - это подробности, возможно ли, что тот же FILE_KEY будет более одного раза в наборе результатов? –

+0

yes BANK_INTL_LOC_TBL - подробности, а FILE_KEY - не один раз –

+2

Без предложения 'order by' в запросе строки, записанные в файл, могут быть в порядке, отличном от порядка' row_number() '.Таким образом, последний запрос, когда исправляется использование уникального ключа, ** не может ** дать вам последние десять строк файла, но всего десять строк, которые существуют где-то в файле. –

ответ

1

Это может быть потому, что у вас есть что-то вроде этого

row_number file_key 
799998  same_number 
799999  same_number 
800000  same_number 
800001  same_number 
800002  same_number 
800003  same_number 
800004  same_number 

потому, что вы заказываете на file_key.

Как вы заметили, что это разные данные? из других столбцов. Итак, вы можете использовать:

SELECT ROW_NUMBER() OVER(order by FILE_KEY desc, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO) rn 

Или (вторая причина), ваш базовый стол менялся между вашими запросами.

UDPDATE: вы можете использовать подсказку use_hash, чтобы ускорить запрос. 5 часов слишком много для этого запроса.

SELECT * FROM (
    SELECT /*+use_hash(rout loc)*/ 
     ROW_NUMBER() OVER(order by FILE_KEY desc, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO) rn, 
     FILE_KEY, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO 
    FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
    WHERE loc.CATALOG_NO = rout.FILE_KEY) 
WHERE rn BETWEEN start AND end; 
+0

Спасибо, Флорин Гита, проверит это и вернется к вам. –

+0

Спасибо Флорин и Шеннон, я использовал этот запрос, и вместо проверки последовательности я создал класс для проверки того, что если в нем есть дублированные записи, но их не было. –

1

В пункте над, заказ уникальным полем в BANK_INTL_LOC_TBL:

SELECT * FROM (
    SELECT ROW_NUMBER() OVER (order by loc.**LOC_KEY** desc) rn, 
     FILE_KEY, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO 
    FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
    WHERE loc.CATALOG_NO = rout.FILE_KEY) 
WHERE rn BETWEEN start AND end 
ORDER BY rn; 

UPDATE: согласно @Shannon Severance комментарий
добавить заказ по п

+0

Спасибо ABCade, попробуем это .. –

+0

Привет, AB, я использовал CATALOG_NO, который является основным ключом BANK_INTL_LOC_TBL, но показывает то же самое последнее 10 записей, что и FILE_KEY в браузере запросов, поэтому будет меняться на CATALOG_NO для генерации правильной и согласованной последовательности строк в файлах ? –

+0

@ neel.1708 Вы пытались сгенерировать 4 файла с моим запросом, а затем проверить? –

0

Если вы у вас есть запасной диск на вашей установке Oracle (что вам нужно!), а вместо того, чтобы запускать внутренний запрос 4 раза, может оказаться, что быстрее выполнить следующие

CREATE TABLE bank_data 
NOLOGGING 
PARALLEL 4 
AS SELECT ROW_NUMBER() OVER (order by FILE_KEY desc) rn, 
    FILE_KEY, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO 
FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
WHERE loc.CATALOG_NO = rout.FILE_KEY); 

Количества параллельности для использования (числа 4 в моем примере здесь) будет зависеть от того, насколько много одновременной работы база данных могут работать, в основном, в зависимости от количества процессоров.

После этого завершения, (которая должна заметно меньше, чем 5 часов!), То вы можете запускать простые выбирает на bank_dump стол, чтобы вытащить записи, которые вы желаете

SELECT * 
FROM bank_dump 
where rn < 200000 

для первого набора данных, для пример.

+0

Спасибо, rejj, Но я только прочитал доступ к этой схеме :) –

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