将多行数据合并到一行中-SQL Server
我有一张有点像这样的桌子将多行数据合并到一行中-SQL Server,sql,sql-server,Sql,Sql Server,我有一张有点像这样的桌子 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
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次)。尝试使用动态透视:
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
检查轴和取消轴的详细信息
注意:如您所见,我使用了一个子查询来查找最新的
标记
。我尽力用更好的东西来代替它,但我做不到。尽管如此,它仍然适用于您。是否最多只能有3个结束日期,或者可以有更多的结束日期?我建议您使用最后3个日期,并可能添加另一列,说明除显示的3个日期之外的其他尝试的数量。否则你会有很多可能,因为我的学生会一次又一次地失败。或者只显示其他尝试的最后结果、标记和计数,因为其他尝试无论如何都将失败。然后,如果你想要特定的测试数据,你可以钻取其中的数据。如果你选择了我们可以使用的最大日期数?我会说,看到超过5个日期会令人惊讶