2015-01-08 4 views
0

나는 테이블이 유사한 구조 방대한 양의 데이터를 포함하고이여러 행 - SQL 서버

ID   NAME   MODULE   STARTDATE   ENDDATE   MARK 
123456  J Bloggs  Module 1  13/01/2014   30/04/2014  FAIL 
123456  J Bloggs  Module 1  13/05/2014   30/08/2014  FAIL 
123456  J Bloggs  Module 1  13/09/2014   30/12/2014  PASS 
123456  J Bloggs  Module 2  13/05/2014   30/08/2014  PASS 
123456  J Bloggs  Module 3  13/01/2015   30/04/2015  FAIL 
234567  A Test  Module 1  13/01/2014   30/04/2014  PASS 
234567  A Test  Module 2  13/05/2014   30/08/2014  FAIL 
234567  A Test  Module 2  13/09/2014   30/12/2014  PASS 

처럼 조금 보이는 테이블이 있습니다. 무엇 최종 결과가

ID   NAME   MODULE   ENDDATE1   ENDDATE2   ENDDATE3   MARK 
123456  J Bloggs  Module 1  30/04/2014  30/08/2014  30/12/2014  PASS 
123456  J Bloggs  Module 2  30/08/2014           PASS 
123456  J Bloggs  Module 3  30/04/2015           FAIL 
234567  A Test  Module 1  30/04/2014           PASS 
234567  A Test  Module 2  30/08/2014  30/12/2014       PASS 

그래서 새 테이블이 것처럼 보일 것이다, 그래서 나는 거의 학생과 촬영 모듈을 기반으로 하나의 행 구조로 여러 행의 데이터의 일부을 연결하면된다하려고 모듈을 기반으로 같은 행에 모든 종료 날짜를 표시하면 가장 최근의 'max (Mark)'표시가 나타납니다. 예제 테이블에 표시되는 3 개 이상의 종료일이있을 수 있습니다. 원래 테이블에 완전히 의존하고 학생이 모듈을 '다시 시작'해야하는 횟수 (최대 4/5 일 수 있음) 일부 경우). 동적 피벗을 사용하여

+0

종료일은 최대 3 개 일 수 있습니까? 아니면 더 많을 수 있습니까? – Matt

+0

지난 3 일 동안 작업 한 후 다른 열을 추가하여 표시되는 3을 제외하고 다른 곳에서 시도하는 양을 명시하는 것이 좋습니다. 그렇지 않으면 학생이 여러 번 반복해서 실패 할 수 있기 때문에 여러 가지 가능성이 있습니다. 또는 다른 시도가 모두 실패 할 것이기 때문에 다른 시도의 마지막 결과, 표시 및 개수 만 표시하십시오. 그리고 특정 테스트 데이터를 원하면 드릴 스루 할 수 있습니다. – Jaques

+0

최대 금액을 고르면 그 값으로 작업 할 수 있습니까? – Matt

답변

0

보십시오 : 피벗 및 피벗 해제 here

IF(OBJECT_ID('tempdb..#table') IS NOT NULL) 
DROP TABLE #TABLE 
CREATE TABLE #TABLE (ID INT, NAME VARCHAR(30),MODULE VARCHAR(30),STARTDATE VARCHAR(30),ENDDATE VARCHAR(30),MARK VARCHAR(30)) 

INSERT INTO #TABLE VALUES 
(123456, 'J Bloggs', 'Module 1', '13/01/2014', '30/04/2014', 'FAIL'), 
(123456, 'J Bloggs', 'Module 1', '13/05/2014', '30/08/2014', 'FAIL'), 
(123456, 'J Bloggs', 'Module 1', '13/09/2014', '30/12/2014', 'PASS'), 
(123456, 'J Bloggs', 'Module 2', '13/05/2014', '30/08/2014', 'PASS'), 
(123456, 'J Bloggs', 'Module 3', '13/01/2015', '30/04/2015', 'FAIL'), 
(234567, 'A Test', 'Module 1', '13/01/2014', '30/04/2014', 'PASS'), 
(234567, 'A Test', 'Module 2', '13/05/2014', '30/08/2014', 'FAIL'), 
(234567, 'A Test', 'Module 2', '13/09/2014', '30/12/2014', 'PASS') 
DECLARE @Columns VARCHAR(MAX) 

SELECT @Columns = STUFF((SELECT ',' + '[' + CONVERT(VARCHAR(30), number, 121) + ']' 
         FROM master..spt_values N 
         WHERE n.number BETWEEN 1 AND (SELECT TOP 1 COUNT(Enddate) 
                 FROM #TABLE 
                 GROUP BY ID,NAME,MODULE 
                 ORDER BY COUNT(Enddate) DESC) 
           AND TYPE = 'P' 
         FOR XML PATH('')), 1, 1, '') 
DECLARE @sql NVARCHAR(MAX) = ' 
SELECT ID, 
     NAME, 
     MODULE, 
     '[email protected]+', 
     (SELECT TOP 1 MARK 
     FROM #table t1 
     WHERE pvt.ID = t1.ID 
       AND pvt.NAME = t1.NAME 
       AND pvt.MODULE = t1.MODULE 
     ORDER BY enddate DESC) AS MARK 
FROM (SELECT ID, 
       NAME, 
       MODULE, 
       ENDDATE, 
       ROW_NUMBER() 
       OVER(
        partition BY ID, NAME, MODULE 
        ORDER BY enddate) AS rn 
     FROM #table) t 
     PIVOT (Max(ENDDATE) 
      FOR rn IN('[email protected]+')) AS pvt 
' 

EXEC sp_executeSQL @sql 

확인 사항.

참고 : 알다시피, 하위 쿼리를 사용하여 최신 Mark을 찾습니다. 나는 그것을 더 나은 것으로 대체하려고 최선을 다했지만 나는 할 수 없었다. 아직도, 그것은 당신을 위해 작동 할 것입니다.