2012-10-29 2 views
1

MS SQL에서 매우 단순한 쿼리를 사용하여 머리를 감쌀 때 문제가 있습니다. 나는 두 개의 테이블을 가지고있다 : EmployeesDepartments.동일한 데이터 테이블의 SQL 하위 쿼리

Employees 표준 항목으로 구성 ID (pkey int), FName, LName, ..., DepartmentID.

DepartmentsDepartmentID, DepartmentName, ..., ManagerID으로 구성됩니다.

Employees.DepartmentID에서 Departments.DepartmentID까지의 관계와 Departments.ManagerIDEmployees.EmployeeID 사이의 관계가 있습니다.

즉, 각 직원에는 부서가 있고 각 부서에는 직원 인 관리자가 있습니다.

직원 이름, ..., 부서 및 부서 관리자를 표시하는보기를 만들려고합니다.

나는이 코드를 사용하는 경우 하나 개 이상의 값이 반환되고 있다는 오류가 점점 계속 : A로부터의 관계에 따라 같은 테이블 (다른 행)에 다시 가입하는 방법에 대한

SELECT 
Employees_1.EmployeeID, Employees_1.FirstName, Employees_1.LastName, 
Departments_1.DepartmentName, 
(SELECT 
    dbo.Employees.LastName 
    FROM dbo.Employees 
    INNER JOIN dbo.Departments 
     ON dbo.Departments.DepartmentManager = dbo.Employees.EmployeeID 
) AS ManagerName 
FROM dbo.Employees AS Employees_1 
INNER JOIN dbo.Departments AS Departments_1 
    ON Employees_1.Department = Departments_1.DepartmentID 
    AND Employees_1.EmployeeID = Departments_1.DepartmentManager 

어떤 아이디어 두 번째 테이블? 당신의 SELECT 절에

답변

3

내가 권합니다 하위 조인 (다른 조인보다 훨씬 비쌉니다)과 비교합니다. 이 두 번째 조인은 dept 테이블에서 부서 관리자 ID의 emp 테이블로 이동하여 직원의 직원 ID로 이동합니다.

은 (내가 선명도의 열 별칭을 추가 -가 필요없는 방법에있는)

SELECT 
    emp.EmployeeID   "EmpID", 
    emp.FirstName   "EmpFirst", 
    emp.LastName   "EmpLast", 
    dept.DepartmentName  "DeptName", 
    deptMgrEmp.FirstName "MgrFirst", 
    deptMgrEmp.LastName  "MgrLast" 
FROM 
    dbo.Employees as emp 
    LEFT JOIN dbo.Departments as dept 
    on emp.DepartmentID = dept.DepartmentID 
    LEFT JOIN dbo.Employees as deptMgrEmp 
    on dept.ManagerID = deptMgrEmp.EmployeeID 

여기에 하위 쿼리 link 대 가입 논의 좋은 스레드입니다.

+0

왼쪽 (외부) 조인을 사용하여 부서/관리자가 할당되었는지 여부에 관계없이 모든 직원이 표시되는지 확인하십시오. 더 이상 연관되지 않은 직원/부서를 숨기려면 내부를 사용하십시오. –

+0

+1에 대한 'JOIN'대하위 쿼리 토론 링크 :) – Palpatim

+0

@ 레이 K 고맙습니다. 그러면 좋은 시작일 수 있습니다. 잘못된 이름을 얻는 것처럼 무언가가 내 코드에서 끔찍하게 잘못되었습니다. MS SQL의 쿼리 작성기는 Left JOIN을 LEFT OUTER JOIN으로 바꿉니다. 불필요하다고 언급 했으므로 열 별칭을 남겼습니다. 내 쿼리에서 키를 표시하고 올바르게 채우지 만 내 쿼리 결과에서 부서 관리자의 이름은 직원 ID로 직원 목록을 가져와야합니다. (예 : -1 직원 deptmgrID = 2, NULL을 표시합니다 .2 번째 직원 deptmgrID = 2, 직원 1의 이름을 보여줍니다 .3 번째 직원 ID = 2, 2의 이름) – gwhenning

0

당신이 기준으로 필터링 할 필요가

을 (dbo.Departments.DepartmentManager = dbo.Employees.EmployeeID ON dbo.Departments 가입 dbo.Employees INNER로부터 dbo.Employees.LastName를 선택) 부서 ID.

그렇다면 모든 부서의 모든 관리자를 반환하겠습니까?

+0

@Ray K- 이전 의견, 코드 복사, 하나 또는 두 개의 변수 이름 변경 및 작동. 이상하게도 GUI를 사용하여 원하는 필드를 선택한 다음 코드를 수정하여 자신의 것과 비슷하게 만들었습니다. 다시 감사합니다! – gwhenning

2
SELECT 
    e.EmployeeId, 
    e.FirstName, 
    e.LastName, 
    d.DepartmentName, 
    m.EmployeeId as ManagerId 
    m.FirstName as ManagerFirstName, 
    m.LastName as ManagerLastName 
FROM 
    dbo.Employees e 
    JOIN dbo.Departments d 
    ON d.DepartmentId = e.DepartmentId 
    JOIN dbo.Employees m 
    ON d.DepartmentManager = m.EmployeeID 

참고 : 테스트되지 않은 코드,하지만 아이디어는 간단하고 (관리자 용) "M"과 Employees 테이블 별명을하기에 키가, 다시에 가입 할 수 있다는 것입니다 관리자의 EmployeeId

+0

SELECT dbo.Employees.EmployeeID를 SELECT TOP (100) PERCENT dbo.Employees.EmployeeID로 변경하는 것으로 나타났습니다. – gwhenning