/ / Кілька рядків даних в один рядок - SQL Server - sql, sql-server

Кілька рядків даних в один рядок - 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       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 для відповіді № 1

Спробуйте скористатися динамічним 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 тут.

ПРИМІТКА: Як ви бачите, я використовував підзапит, щоб знайти останні Mark. Я спробував все можливе, щоб замінити його на щось краще, але я не міг "т".