2016-08-31 2 views
2

У меня есть 3 таблицыНевозможно сделать желанной JOINS между несколькими таблицами

План:

plan_id emp_id duration 
    123  1010 30 
    456  1011 40 
    789  1012 60 

PlanEmp:

plan_id emp_id 
123 2131 
456 3131 
789 4131 

Emp:

emp_id Name 
1010 Andy 
1011 Cole 
1012 John 
2131 Sam 
3131 Kim 
4131 Ray 

Желаемая Итоговый результат:

plan_id Name duration 
123  Andy 30 
123  Sam 30 
456  Cole 40 
456  Kim 40 
789  John 60 
789  Ray 60 

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

SELECT P.plan_id 
     ,E.Name 
     ,P.duration 
FROM Plan P 
LEFT JOIN Emp E 
    ON P.emp_id = E.emp_id 
LEFT JOIN PlanEmp PE 
    ON P.plan_id = PE.plan_id 

Я не могу понять, как вытащить детали Employee с помощью таблицы PlanEmp и таблица плана для получить итоговый результат.

+2

план союза и planemp, а затем присоединиться к – techspider

+0

ВЫБЕРИТЕ P.plan_id , E.Name , P.duration FROM Plan P LEFT JOIN Emp E ON P.emp_id = E.emp_id должен сделайте это –

+1

Что произойдет, если на планирование плана/сотрудника больше одного времени - какой из них вы используете в качестве основы в другой таблице? Если данные заполняются по-разному, почему вы должны повторно использовать данные из другой таблицы, и уверены, что эти столбцы действительно коррелируют? –

ответ

3

Это должно работать:

SELECT sub.plan_id, sub.emp_id, Emp.name, Plan.duration 
FROM 
(SELECT plan_id, emp_id 
FROM Plan 
UNION 
SELECT plan_id, emp_id 
FROM PlanEmp) sub 
LEFT JOIN Emp 
ON sub.emp_id = Emp.emp_id 
LEFT JOIN Plan 
ON sub.plan_id = Plan.plan_id 
ORDER BY plan_id 

Испытано здесь: http://sqlfiddle.com/#!9/21ca79/4

2

Используйте приведенный ниже сценарий.

;With cte_1 
    As(select plan_id,emp_id 
     From plan 
     UNION 
     Select plan_id,emp_id 
      From plan_emp) 

    Select c.plan_id,e.Name,p.Duration 
     From cte_1 c 
     Join plan p on c.plan_id=p.plan_id 
      Join emp e on c. Emp_id=e.emp_id 
+0

Могу ли я предложить добавить к вашим ответам больше, чем код? Предоставление кому-либо ответа на вопрос без объяснения логики приведет только к тому, чтобы следить за вопросами и/или следить за ошибками в их коде, если они не знают, что делает ваш код, или почему вы выбрали методы, которые вы делаете. «Только ответы на код» обычно считаются ответами низкого качества. Это, например, намного лучше http://stackoverflow.com/a/39020960/6167855, и больше ответов, как это поможет вам с вашей ссылкой «Цель очков» здесь http://stackoverflow.com/a/39247701/ 6167855 и действительно поможет другим пользователям. Просто предложение. – scsimon

0

Я уверен, что есть логическое объяснение для этого и так как моя репутация не на уровне комментировать пока нет, но почему emp_id на обоих Plan and PlanEmp tables? Если вы можете нормализовать это, было бы неплохо переместить emp_id с Plan table в PlanEmp table.

+0

Он денормализован для производительности, а также потому, что логически люди, перечисленные в «Плане», имеют разные роли, чем те, что в «PlanEmp», и их данные заполняются по-разному. – AS91

+0

Тогда включение UNION должно работать на вас. –

0

Ваш дизайн таблицы не следует необходимых методов нормализации. Вы должны объединить таблицу Plan и EmpPlan.

или

Ваш дизайн должен быть (Нормализовать больше):

Table: Plan 
Plan_ID 
Duration 

Table: PlanEmp 
Plan_ID 
Emp_ID 

Существующая структура может быть запрошена с несколькими способами, но они не могут эффективно. Другой способ:

Select ISNULL(P.plan_id, PE.plan_id) Plan_ID, E.Name, 
(Select Duration from @Plan pp Where pp.plan_id = ISNULL(P.plan_id, PE.plan_id)) as Duration 
from Emp E 
left Join @lan P on E.emp_id = P.emp_id 
left Join PlanEmp PE on E.emp_id = PE.emp_id 
Where P.emp_id IS NOT NULL or PE.emp_id is not null 
Смежные вопросы