我有一张看起来有点像这样的桌子
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 :(得分:0)
尝试使用Dynamic Pivot:
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,
'+@Columns+',
(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('+@Columns+')) AS pvt
'
EXEC sp_executeSQL @sql
检查Pivot和Unpivot here的详细信息。
注意:正如您所看到的,我使用子查询来查找最新的Mark
。我尽力用更好的东西代替它,但我做不到。不过,它对你有用。