2015-11-06 3 views
1

У меня есть таблица с именем PROF, из которой мне нужно взять определенные коды, которые укладываются из x1..x20 и y1..y20 (всего 40 столбцов), которые необходимо проверить в другая таблица таблицы CROSSREF для ссылочных кодов. Проблема здесь в том, что в этой таблице CROSSREF есть одно-много картирование.Отчаянно нужна помощь по логике преобразования

table PROF 
--------- 

mem_id cl_id line_no x1..x20 y1..y20 

table CROSSREF 
-------------- 
refx refy 

здесь x1 сравнивается с z1 в REFx и эталонное значение в refy поле должно быть вытащены, который имеет от 1 до многих отношениях ..

для например:

refx refy 
---------- 
z1 -> a1 
     a3 
     a2 
z2 -> a10 
     a50 

так здесь для x1 из таблицы PROF, у меня есть a1, a2, a3 коды. согласно требованию, a1 перемещается в x1, a3-x2 и a2-x3. и нужно заполнить до x20 .. Я думаю, что сначала мне придется тянуть значения до тех пор, пока я не смогу разместить до x1..x20, просмотрев таблицу CROSSREF и оставив остальные коды в таблице PROF, если им не удастся разместить.

Окончательное преобразование

x1 -> a1 
x2 -> a3 
x3 -> a2 
x4 -> a10 
x5 -> a20 and so on 

Я знаю его слишком сложным, я сказал предложения изменить CrossRef к одному к одному отображения, но требование не изменилось до сих пор.

+0

Сделано использование вложенной таблицы для хранения значений refy при сравнении с таблицей PROF x1, x2, x20, а затем удалены дубликаты среди значений refy, если они используются с использованием MULTISET а затем обновляет значения обратно в x1, x2..x20. – blackpanther

ответ

0

Итак, после немного возиться, я думаю, что нашел ответ. Предполагая, что я правильно понимаю ваш вопрос.

Ответ ниже использует

  1. UNPIVOT: (который доступен в Oracle 11g, что вы меченой) для того, чтобы транспонировать столбцы x1, .. Y20 в строки (40 строк).
  2. WITH Статья: Чтобы присоединиться к двум таблицам.

Поскольку нет единого столбца не для объединения двух таблиц, я использовал rownum

WITH q1 AS 
( 
     SELECT xy, 
       ROWNUM r 
     FROM prof unpivot (xy FOR x IN (x1, 
             x2, 
             x3 , 
             x4, 
             x5 --add rest of the columns here 
              ))), 
q2 AS 
( 
     SELECT refx, 
        refy, 
        ROWNUM r 
     FROM  crossref 
     ORDER BY refx, 
        refy) 
SELECT  q1.xy, 
      q2.refy 
FROM  q1 
inner join q2 
ON   q1.r = q2.r; 

Здесь FIDDLE

Результат в течение первых 5 строк:

enter image description here

+0

общее поле между двумя таблицами: refx и x1..x20, y1..y20 .. поэтому каждый x1 нужно сравнить с значением refx, и необходимо выделить соответствующие потребности refy, многие из которых содержат от одного до многих строк. который я показал в примере – blackpanther

+0

@blackpanther Могу ли я понять, что не так с результатом, который я опубликовал только сейчас? Разве это не то, что вы опубликовали как «Окончательная трансформация»? – Hawk

+0

Я ожидал чего-то вроде Эмиля Моисея, упомянутого здесь. Я также добавил комментарий для этого ответа – blackpanther

0

Если я правильно понял, вы хотите переместить значения из crossref t способный в таблицу prof. Если да, то вы можете использовать курсор для перебора значений CrossRef и использовать переключатель заявление, чтобы сделать вставки:

begin 
    for r_crossref in (select refx, refy from crossref) loop 
    case r_crossref.refx 
     when 'z1' insert into prof (x1) values (r_crossref.refy); 
     when 'z2' insert into prof (x2) values (r_crossref.refy); 
     ... 
    end case; 
    end loop; 
end; 
/
commit; 

Обновление на основе обратной связи владельца. Если мое предположение верно, вам нужно вставить одну строку для каждой группы zN в таблицу PROF и обновить все значения xN для этой соответствующей строки, поэтому решение ниже будет работать. Тем не менее, проблема кажется немного странной, или, по крайней мере, у нас недостаточно информации об этом. Например, что произойдет, если у вас будет более 20 строк в таблице CROSSREF для одного значения zN и так далее ...

begin 
    for r_crossref_refx in (select distinct refx from crossref) loop 
    insert into prof(SOME_MEM_ID_BASED_ON_YOUR_BUSINESS_LOGIC, ...) values (...); 
    for r_crossref_refy in (select refy from crossref where refx = r_crossref_refx.refx) loop 
     case r_crossref.refy 
     when 'z1' update prof set x1 = r_crossref_refy.refy where mem_id = SOME_MEM_ID_BASED_ON_YOUR_BUSINESS_LOGIC; 
     when 'z2' update prof set x2 = r_crossref_refy.refy where mem_id = SOME_MEM_ID_BASED_ON_YOUR_BUSINESS_LOGIC; 
     ... 
     end case; 
    end loop; 
    end loop; 
end; 
/
commit; 
+0

Мне нужно проверить для каждого значения x1, x2 ... до x20 в таблице PROF с значением refx CROSSREF и принять refy .. в моем случае для одного refx есть много refy. как показано в примере. Мне также нужно взять эти несколько значений .. и попытаться создать новый набор x1, x2, x3 .. со значениями, как показано, например, для. и окончательное преобразование и, наконец, обновить эти новые наборы в таблицу PROF для cl_id, mem_id и line_no – blackpanther

+0

Я обновил свой ответ, но на случай, если я правильно понял вашу проблему, все еще есть проблемы с бизнес-логикой, которые вам понадобятся ручку самостоятельно. –

0

Сделано использование вложенной таблицы для хранения значений refy по сравнению с PROF таблицы x1, x2,, x20, затем удаляют дубликаты среди refy значений, если какие-либо помощи MULTISET, а затем обновленные значения обратно в x1 , x2..x20 таблицы PROF.

Используется неявный курсор, вложенная таблица, MULTISET - объединить каждый набор и удалить дубликаты среди них и построил окончательный набор, который должен быть обновлен назад, как показано в окончательном преобразовании ..

Благодаря друзьям, которые помогли мне сделать это, а также @Hawk и @EmilMoise

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