2017-02-07 4 views
1

Мне нужно написать запрос, чтобы заменить одно из значений столбца значением из другой строки в той же таблице. Я попытался использовать простое внутреннее соединение, но я не вижу результатов, которые мне нужны.Может INNER JOIN заменить значение столбца на другое значение из той же таблицы - для всех строк

Вот пример таблицы BANK_LOANS:

MONTH_ID LOAN_NUMBER BANK_NAME  AMOUNT 
======== =========== ==========  ======== 
76   00-100   Bank One  100.00 
75   00-100   The Bank One 150.00 
74   00-100   Bank 1   150.00 
76   00-200   Another Bank 300.00 
75   00-200   Another Bank 500.00 

Данные загружаются из внешних источников, которые не проверяют название банка, поэтому написание на имя банка в течение определенного количества кредитов может возможно варьировать , Клиент хочет, чтобы BANK_NAME находился в базе данных для максимального MONTH_ID, который будет использоваться для всех результатов для этого LOAN_NUMBER, и они хотят, чтобы результаты сортировались BANK_NAME. Так, например, кредит 00-100 нуждается в BANK_NAME «Bank One» для всех строк.

Я попытался с помощью внутреннего соединения, чтобы сделать это, но не получал правильные результаты

SELECT name.BANK_NAME, 
     bl.LOAN_NUMBER, 
     bl.AMOUNT 
FROM BANK_LOANS  
INNER JOIN BANK_LOANS home 
    ON name.LOAN_NUMBER = bl.LOAN_NUMBER 
    AND name.MONTH_ID = 67 --the max id provided to the query 
ORDER BY name.BANK_NAME, bl.LOAN_NUMBER, bl.MONTH_ID DESC 

Я думаю, что он работает с суб-запроса, но это своего рода уродливый. Мне было интересно, есть ли лучший способ (лучшие практики) для достижения этого с помощью объединений или других функций оракула.

Это похоже на работу, но он просто чувствует себя неправильно:

SELECT name.BANK_NAME, 
     bl.LOAN_NUMBER, 
     bl.AMOUNT 
FROM BANK_LOANS, 
    (SELECT bl2.BANK_NAME, bl2.LOAN_NUMBER 
     FROM BANK_LOANS 
     WHERE bl2.MONTH_ID = 76 --max month id provided to query 
    ) name 
WHERE name.LOAN_NUMBER = bl.LOAN_NUMBER 
ORDER BY name.BANK_NAME, bl.LOAN_NUMBER, bl.MONTH_ID DESC 
+1

Любой 'пункт от', который включает в себя запятой«чувствует себя неправильно «. –

+0

@ GordonLinoff - за небольшим количеством исключений; например, материализованные представления с быстрым обновлением не поддерживают стандартный синтаксис соединения, для этого требуется старый синтаксис Oracle с условием объединения в предложении WHERE. Только Oracle знает, почему. – mathguy

ответ

2
with 
    test_data (month_id, loan_number, bank_name, amount) as (
     select 76, '00-100', 'Bank One' , 100.00 from dual union all 
     select 75, '00-100', 'The Bank One', 150.00 from dual union all 
     select 74, '00-100', 'Bank 1'  , 150.00 from dual union all 
     select 76, '00-200', 'Another Bank', 300.00 from dual union all 
     select 75, '00-200', 'Another Bank', 500.00 from dual 
    ) 
-- end of test data (not part of the solution). 
-- SQL query begins BELOW THIS LINE; use with your table. 
select month_id, loan_number, 
     first_value(bank_name) 
       over (partition by loan_number order by month_id desc) as bank_name, 
     amount 
from test_data 
; 

MONTH_ID LOAN_N BANK_NAME AMOUNT 
-------- ------ ------------ ------ 
     74 00-100 Bank One  150 
     75 00-100 Bank One  150 
     76 00-100 Bank One  100 
     75 00-200 Another Bank 500 
     76 00-200 Another Bank 300 

5 rows selected. 
+0

Спасибо @mathguy за сообщение! Я буду исследовать функцию first_value() и предложение раздела и попытаюсь выполнить это в нашем запросе. – Roy

+0

@Roy - то, что вам нужно для «исследования», - это общая концепция ** аналитических функций ** (иногда называемых, неправильно, ** оконных функций **). Предложение 'partition' является одним из основных понятий, и' first_value() 'является одной из аналитических функций. Преимущество состоит в том, что все они работают очень схожими способами, поэтому с разумным количеством времени, затрачиваемым на их изучение, вы получаете сразу множество инструментов. Удачи! – mathguy

-1

Использовать аналитические функции:

select bl.loannumber, bl.amount, 
     max(bank_name) keep (dense_rank first order by month_id desc) over (partition by loannumber) as bank_name 
from bank_loans bl; 
+0

Это агрегированная функция (нет предложения раздела), поэтому синтаксический анализатор будет вызывать синтаксическую ошибку, так как не существует предложение GROUP BY. – mathguy

-1
SELECT month_id, 
    loan_number, 
    MIN(bank_name) over(PARTITION BY loan_number ORDER BY month_id DESC), 
    amount 
FROM bank_loans; 
+1

Неправильная аналитическая функция (и, с предложением ORDER BY, в любом случае она будет MIN по движущемуся окну). – mathguy

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

  • Нет связанных вопросов^_^