Проблема самостоятельного объединения SQL с нулевыми значениями - PullRequest
0 голосов
/ 02 февраля 2011

Давайте возьмем классический пример самостоятельного объединения таблицы Employee, где у нас есть столбцы empId,managerId,empName,Managername.Я пытаюсь увидеть это для каждого сотрудника, который является менеджером, и затем соединяю имя менеджера с другим именем в таблице Name.Теперь у меня проблемы с тем, что идентификатор менеджера может быть нулевым для некоторых записей.В этих случаях sql не работает, так как mgr.name имеет значение null для строки, в которой mgrId имеет значение null:

SELECT emp.Name, mgr.Name FROM Employee e
LEFT JOIN Employee mgr ON e.empId=mgr.mgrId 
JOIN Name nm ON nm.name = mgr.Name

Может кто-нибудь предложить решение для этого?

Извините за упрощение проблемы: это больше похоже на строку каждого сотрудника, я также хочу строку mgr (строка, где mgrId - empId) и затем присоединяю атрибуты строки mgr к другим таблицам.Примерно так:

select 
   emp.empId,mgr.empId,dept.deptName 
from Employee emp  
JOIN Address addr on 
   emp.houseNo = addr.houseNo  
JOIN dept dept on 
   dept.deptAddress = addr.deptAddress  
LEFT JOIN Employee mgr on 
   emp.empId = mgr.empId  
JOIN Address address on 
   mgr.houseNo = address.houseNo  
JOIN dept department on 
   department.houseNo=address.deptAddress  
where 
   department.deptId=dept.deptId  

Использование всех левых объединений для этого не сработало.Спасибо за помощь.

Ответы [ 3 ]

8 голосов
/ 02 февраля 2011

После того, как вы вводите левое соединение, вы, как правило, хотите следовать всем последующим соединениям также с помощью LEFT. Единственное ВНУТРЕННЕЕ СОЕДИНЕНИЕ в цепочке сводит все до него и к ВНУТРЕННЕМУ СОЕДИНЕНИЮ.

SELECT 
    emp.Name, mgr.Name 
FROM Employee e
LEFT JOIN Employee mgr ON 
    e.empId = mgr.mgrId 
LEFT JOIN Name nm ON 
    nm.name = mgr.Name
2 голосов
/ 02 февраля 2011

Во-первых, разве у вас нет обратных слов соединения?

         ON e.empId = mgr.mgrId 

не должно быть

         ON e.mgrId = mgr.empId

Даже если у вас работает, таблица с именем "mgr" должна содержать запись с mgr.empId и mgr.name, чтобы она была понятна.

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

В-третьих, тот факт, что 2 столбца в наборе результатов имеютто же имя (имя) может привести к проблемам позже - плохая практика, если ничего больше.

Это SQL, который я бы использовал:

SELECT emp.Name, '(none)' AS Manager 
FROM Employee emp
WHERE NOT EXISTS (SELECT 1
    FROM Employee mgr 
    WHERE mgr.empId = emp.mgrId)

UNION ALL

SELECT emp.Name, mgr.Name AS Manager 
FROM Employee emp
JOIN Employee mgr ON emp.mgrId=mgr.empId 
JOIN Name nm ON nm.name = mgr.Name
ORDER BY 1, 2

Не беспокойтесь, если это выглядит неэффективно,современный компилятор SQL в большинстве случаев заканчивается одним и тем же, независимо от того, как вы его пишете.

Но сначала я бы запустил этот SQL, чтобы посмотреть, есть ли у меня сотрудники, у которых нет записи в имени.Таблица и исправить их:

SELECT *
FROM Employee e
LEFT JOIN Name nm 
ON nm.name = e.Name
WHERE nm.name is null
0 голосов
/ 02 февраля 2011

Просто переместите предложение ON туда, где оно более уместно

SELECT emp.Name, mgr.Name
FROM Employee e
    LEFT JOIN Employee mgr 
         JOIN Name nm
         ON nm.name = mgr.Name
    ON e.empId=mgr.mgrId 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...