2015-02-20 4 views
3

У меня возникла проблема с sql. Я хочу присоединиться к двум таблицам, преподавателю и классу. Условие состоит в том, что у сотрудника есть один столбец типа u0871457, где в качестве инструктора класса EmplId используется как «00871457».Как присоединиться к двум таблицам на основе значений подстроки полей?

Я просто хочу заменить первый символ EmplId на 'u', чтобы присоединиться к строке, идущей от unid. Как я могу это сделать? Я пробовал это до сих пор:

select e.name, i.name 
from Employee e 
inner join Instructor i on SUBSTR(e.id,1, LENGTH(e.id)) = SUBSTR(i.id,1, LENGTH(i.id)) 

но это приводит к пустому набору результатов.

Любая помощь будет оценена по достоинству. Спасибо за ваше время!

+0

Почему вы ПОДПИСАЛИ обе стороны? Из вашего описания вы хотите только SUBSTR с одной стороны? – Ditto

ответ

5

Так много способов сделать это , Было бы неплохо взглянуть на план объяснения по-разному, прежде чем перейти к определенному методу.Например, если есть индекс-функции на основе EMPLOYEE таких как SUBSTR(id, 2, LENGTH(id) - 1) то вы хотите использовать, что в вашем запросе:

SELECT e.name, i.name 
    FROM employee e INNER JOIN instructor i 
    ON SUBSTR(e.id, 2, LENGTH(e.id) - 1) = SUBSTR(i.id, 2, LENGTH(i.id) - 1); 

Другой вопрос, если значения в столбце id всегда такой же длины в EMPLOYEEиINSTRUCTOR. Что делать, если они имеют разную длину? Возможно, у вас больше дополнений, чем у другого. Кроме того, они всегда будут цифр отдельно от ведущих u? Если да, то это может быть стоит попробовать безопасное TO_NUMBER() преобразование:

SELECT e.name, i.name 
    FROM employee e INNER JOIN instructor i 
    ON TO_NUMBER(REGEXP_SUBSTR(e.id, '\d+$')) = TO_NUMBER(REGEXP_SUBSTR(i.id, '\d+$')); 

Еще одна вещь, которую вы можете рассмотреть, однако - есть причина для ведущих u в колонке EMPLOYEEid? Могут ли быть другие ведущие персонажи? Стоит ли ведущий u (нарушая первую нормальную форму, но что происходит)?

+0

Это, безусловно, лучший ответ. Удивительное объяснение! Большое спасибо за то, что обучил меня этому. Очень ценится. – userx

3

Oracle использует 1 в качестве основы своих индексов, поэтому substr('aaa',1,3) эквивалентен 'aaa'. Вам нужно использовать 2 как второй параметр substr, чтобы выполнить то, что вы пытаетесь сделать.


Помимо этого, возможно, вам будет лучше сменить одну сторону, если сможете. Если символы префикса последовательны, вы можете сделать это:

SELECT e.name, i.name 
FROM employee e INNER JOIN instructor i ON REPLACE (e.id, 'u', '0') = i.id 

Это потенциально может позволить базе данных использовать индекс instructor, что не было бы возможно с вашим решением.

+0

Спасибо за решение и за дополнительную информацию, чтобы это лучше! – userx

+0

', что было бы невозможно с вашим решением' - можно использовать индекс на основе функций:' SUBSTR (id, 2, LENGTH (id) - 1) ' –

1
select e.name, i.name 
from Employee e 
inner join Instructor i on SUBSTR(e.id, 2, LENGTH(e.id) - 1) = SUBSTR(i.id, 2, LENGTH(i.id) - 1) 

В вашей БД используется индексирование на основе 1.

+0

Спасибо за ответ! – userx

3

Позиция символа неправильная. Вы должны начать свою подстроку в позиции 2 (первый символ вашей строки равен 1, а не 0). С другой стороны, вы используете функцию SUBSTR для обеих строк, пока вы должны использовать только идентификатор сотрудника. Будьте осторожны, если оба идентификатора являются строками, длина будет отличаться.

Если вы просто хотите изменить «u» на идентификаторе сотрудника, попробуйте использовать функцию TRANSLATE.

TRANSLATE возвращает char со всеми вхождениями каждого символа в from_string, замененным соответствующим символом в to_string. Символы в char, которые не находятся в from_string, не заменяются. Аргумент from_string может содержать больше символов, чем to_string. В этом случае дополнительные символы в конце from_string не имеют соответствующих символов в to_string. Если эти дополнительные символы появляются в символе, они удаляются из возвращаемого значения.

Синтаксис

──TRANSLATE── ('символьные', 'from_string', 'to_string') ──> <

Pl/SQL Example 
TRANSLATE ('abcd', 'ab', '12') ==> '12cd' 
TRANSLATE ('12345', '15', 'xx') ==> 'x234x' 
+0

Спасибо за вашу идею перевода! – userx

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