2012-01-24 3 views
0

직원 교육을위한 MS Access 데이터베이스가 있으며 각 직원이 일년에 두 번씩 필요로하는 클래스가 있습니다.행 기반 데이터를 열 기반으로 액세스 ID

그 클래스에 대한 표는 다음과 같습니다

EmployeeID ClassDate ClassHours 
1   1/1/2011  8 
1   7/31/2011  7 
2   2/1/2011  8 
2   8/31/2011  7 
3   3/1/2011  8 
3   9/30/2011  7 

나는 테이블과 같은 형식의 싶지 :

EmployeeID ClassDate_1 ClassHours_1 ClassDate_2 ClassHours_2 
1   1/1/2011  8   7/31/2011  7 
2   2/1/2011  8   8/31/2011  7 
3   3/1/2011  8   9/30/2011  7 

가 어떻게 두 번째 클래스 날짜를 이동하는 쿼리를 작성 않으며, EmployeeID를 기반으로 같은 행에 시간 필드?

나는이 사이트를 통해 연구했으며 모든 가능한 해결책은 내가 습득하려는 것에 지나치게 복잡해 보입니다.

귀하의 도움에 감사드립니다.

감사

+0

나는 그렇게 보이는 테이블을하지 않을 것 - 그것은 데이터베이스 정규화의 첫 번째 규칙을 위반하는 것입니다. 직원 테이블과 클래스 테이블을 유지하고 원하는 결과를 제공하는 쿼리를 작성할 수 있습니다. – maneesha

+0

안녕하세요 maneesha. 그것이 내가하고 싶은 일입니다.원래 테이블을 그대로 유지하지만 EmployeeID에 공통 인 필드를 같은 행으로 이동시키는 쿼리를 만듭니다. 그 결과를 얻기 위해 쿼리를 작성하는 방법을 모르겠습니다. – ultraviolet

답변

1

당신은 하위 선택


SELECT 
    X.EmployeeID, 
    X.d1 AS ClassDate_1, ec1.ClassHours AS ClassHours_1, 
    X.d2 AS ClassDate_2, ec2.ClassHours AS ClassHours_2 
FROM 
    ((SELECT e.EmployeeID, Min(e.ClassDate) AS d1, Max(e.ClassDate) AS d2 
     FROM employee_classes AS e 
     GROUP BY e.EmployeeID) AS X 
     INNER JOIN employee_classes AS ec1 
      ON X.EmployeeID = ec1.EmployeeID AND X.d1 = ec1.ClassDate 
    ) 
    INNER JOIN employee_classes AS ec2 
     ON X.EmployeeID = ec2.EmployeeID AND X.d2 = ec2.ClassDate; 
가 또는 쿼리로 중첩 된 선택을 저장할 수있는 쿼리를 만들어야합니다 (의는 query1를 호출하자) :

SELECT e.EmployeeID, Min(e.ClassDate) AS d1, Max(e.ClassDate) AS d2 
FROM employee_classes AS e 
GROUP BY e.EmployeeID 

두 번째 쿼리에서 사용

시간이

실제로 간단한 해결책이

SELECT e.EmployeeID, Min(e.ClassDate) AS ClassDate_1, Max(e.ClassDate) AS ClassDate_2 
FROM employee_classes AS e 
GROUP BY e.EmployeeID 

표시되지 않은 경우
SELECT 
    X.EmployeeID, 
    X.d1 AS ClassDate_1, ec1.ClassHours AS ClassHours_1, 
    X.d2 AS ClassDate_2, ec2.ClassHours AS ClassHours_2 
FROM 
    (query1 AS X 
     INNER JOIN employee_classes AS ec1 
      ON X.EmployeeID = ec1.EmployeeID AND X.d1 = ec1.ClassDate 
    ) 
    INNER JOIN employee_classes AS ec2 
     ON X.EmployeeID = ec2.EmployeeID AND X.d2 = ec2.ClassDate; 

그것은 그러나 그것은 테이블이 EmployeeIDClassDate으로 분류된다고 가정 훨씬 쉬울 것입니다. 이 가정은 자연 정렬 순서가 보장되지 않으므로 안전하지 않습니다. 액세스는 언제든지 다른 방식으로 레코드를 재구성하도록 "결정"할 수 있습니다.

SELECT 
    EmployeeID, 
    First(ClassDate) AS ClassDate_1, First(ClassHours) AS ClassHours_1, 
    Last(ClassDate) AS ClassDate_2, Last(ClassHours) AS ClassHours_2 
FROM 
    employee_classes 
GROUP BY 
    EmployeeID 
ORDER BY 
    EmployeeID; 

는 여기서 다시 하위 선택은 하위 쿼리 또는 두 번째 쿼리 중 하나가 필요합니다,

SELECT 
    EmployeeID, 
    First(ClassDate) AS ClassDate_1, First(ClassHours) AS ClassHours_1, 
    Last(ClassDate) AS ClassDate_2, Last(ClassHours) AS ClassHours_2 
FROM 
    (SELECT * FROM employee_classes ORDER BY EmployeeID, ClassDate) 
GROUP BY 
    EmployeeID 
ORDER BY 
    EmployeeID; 

되었던간에 도움을 줄 수 있습니다.

+0

Olivier 대단히 감사합니다. 나는 당신의 첫 번째 예를 사용했고 그것은 잘 작동했습니다. 그러나 때로는 직원이 코스를 한 번만 가져 왔고 하나의 행 항목 만 있습니다. 어떻게 그 ClassDate_2 <> ClassDate_1을 확인하기 위해 WHERE 절을 구현합니까? – ultraviolet

+0

'IIf (X.d1 = X.d2, null, X.d2) AS ClassDate_2, IIf (ec1.ClassHours = ec2.ClassHours, null, ec2.ClassHours) AS ClassHours_2'. 그러나이 솔루션은 직원 당 최대 두 개의 클래스에서만 작동합니다. 수업이 더 많은 경우 ChrisPadgham의 솔루션을 사용해야합니다. –

+0

올리비에, 도와 줘서 고마워. 이 솔루션은 내가 원하는만큼 정확하게 작동합니다. 두 번째 IIF 문을 첫 번째 IIF 문과 같은 식으로 변경해야했습니다. ClassHours는 항상 동일하므로 ClassDates가 시간을 얻는 조건과 동일한 지 확인하기 위해 변경했습니다. 다시 한 번 귀하의 솔루션에 감사드립니다. – ultraviolet

0

그것은 당신이 그들이 여기 표시하면 결과와 함께 할 계획 무엇을 달려는 (날짜 이후 괄호 안에 시간과 함께) 값 셀의 ClassDate 및 시간을 포함하는 크로스 탭 쿼리

TRANSFORM Last([ClassDate] & " (" & [ClassHours] & ")") AS Details 
SELECT Classes.EmployeeId 
FROM Classes 
GROUP BY Classes.EmployeeId 
PIVOT "Class " & (DCount("[ClassNumber]","[Classes]","[ClassDate]<#" & Format$([ClassDate],"dd-mmm-yyyy") & "# AND [EmployeeId]=" & [EmployeeId])+1); 
입니다

이것은 교사 당 2 명뿐만 아니라 모든 클래스 수를 허용합니다.

output from crosstab http://www.solsup.com.au/images/classes.jpg

관련 문제