2013-05-26 2 views
2

У меня есть 2 стола: Candidates и Jobs.Внутреннее соединение 2 таблицы по 2 категориям и нескольким столбцам

В Jobs имеются столбцы Profession и Subprofession.

Для каждой строки в Candidates есть 8 колонок:

Selected_Profession1, Selected_Subprofession1, 
Selected_Profession2, Selected_Subprofession2, 
Selected_Profession3, Selected_Subprofession3, 
Selected_Profession4, Selected_Subprofession4 

Я хотел бы сделать запрос, который будет выбирать все рабочие места, чьи профессии и subprofession в одном из соответствующих полей в Candidates таблицы.

Итак, давайте говорить, что мы имеем следующую Jobs таблицу:

(profession subprofession) -----> (100, 200) 
            (100, 201) 
            (101, 200) 
            (101, 201) 

и следующую таблицу кандидатов:

(prof1 subprof1 prof2 subprof2 prof3 subprof3 prof4 subprof4) ----> 
(100, 200,  300, 400,  100, 200,  100, 300) 
(101, 200,  102, 200,  300, 200,  200, 300) 
(100, 200,  300, 400,  101, 201,  100, 300) 
(101, 101,  200, 200,  300, 300,  400, 400) 

Запрос будет возвращать строки 1, 3 и 4 из таблицы рабочих мест (из-за Кандидат 1 имеет пару 100, 200, а кандидат 2 имеет пару 101, 200, а кандидат 3 имеет пару 101, 201).

Надеется, что это достаточно ясно ...

+1

Если бы я был вами, я бы нормализовал ваши структуры данных, прежде чем идти дальше. – podiluska

ответ

4

Вы можете сделать объединение по нескольким полям с or условия:

select j.* 
from jobs j join 
    candidates c 
    on (j.prof = c.prof1 and j.subprof = c.subprof1) or 
     (j.prof = c.prof2 and j.subprof = c.subprof2) or 
     (j.prof = c.prof3 and j.subprof = c.subprof3) or 
     (j.prof = c.prof4 and j.subprof = c.subprof4); 

Если у вас есть большие таблицы, производительность на это не будет очень хорошо. Вы можете исправить структуру данных, чтобы получить лучшую производительность, имея таблицу CandidateProf, где каждая пара prof/subprof находится в другой строке.

С учетом структуры данных вы получите лучшую производительность с отдельными объединениями для каждой группировки prof/subprof, в частности, имея индекс в паре. Проблема заключается в следующем: select. Таким образом:

select distinct j.* 
from jobs j lef outer join 
    candidates c1 
    on (j.prof = c1.prof1 and j.subprof = c1.subprof1) left outer join 
    candidates c2 
    on (j.prof = c2.prof2 and j.subprof = c2.subprof2) left outer join 
    . . . 
where c1.prof1 is not null or c2.prof1 is not null or 
     c3.prof1 is not null or c4.prof1 is not null 

И вам нужно удалить дубликаты, потому что один кандидат может иметь несколько квалификаций.

+0

Второй запрос выглядит хорошо, просто выберет j. *, Поскольку OP хочет, чтобы отдельные строки из таблицы заданий делали запрос немного проще (запрос вернет строки 1, 3 и 4 из таблицы Jobs ...). – sgeddes

+0

@sgeddes. , , Спасибо, что указали это. Я изменил решение, чтобы вытащить задания, а не кандидатов (вам по-прежнему нужен отдельный во втором случае, хотя, поскольку несколько кандидатов могут претендовать на создание нескольких строк). –

+0

+1 Выглядит хорошо - думал, как я написал это в своем комментарии. – sgeddes

0

Если ваши структуры данных были нормализованы, этот запрос становится проще, и ваша база данных становится более гибкой.

IE: Ваш стол должен выглядеть как

CandidateID ProfessionOrder Profession SubProfession 
1   1    100  200 
1   2    300  400 
... 
2   1    101  200 

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

select 
    candidateid 
from 
    jobs 
inner join 
(
    select 
     candidateid, prof1 as profession, subprof1 as subprofession 
    from candidates 
    union 
    select 
     candidateid, prof2 , subprof2 
    from candidates 
    union 
    select 
     candidateid, prof3 , subprof3 
    from candidates 
    union 
    select 
     candidateid, prof4 , subprof4 
    from candidates 
) candidates 
    on jobs.profession = candidates.profession 
    and jobs.subprofession = candidates.subprofession 
+0

Для этого нужна помощь, чтобы быть точным - где все ваши предложения FROM? – sgeddes

+0

@sgeddes Совершенно верно. Моя ошибка – podiluska

+0

Не беспокойтесь - еще 4, и тогда это будет хорошо выглядеть. – sgeddes

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