Преобразование двух столбцов в 5 строк в sql server

#sql-server

#sql-сервер

Вопрос:

У меня есть временная таблица с данными.

 select * 
from #test
  

обрабатывает этот вывод:

 reg  | Years
---------------
6279 | 2016
6641 | 2016
8347 | 2016
6228 | 2015
8596 | 2015
7596 | 2015
6352 | 2015
1245 | 2014
5248 | 2014
6359 | 2014
6785 | 2014
9578 | 2013
4398 | 2013
2986 | 2013
7296 | 2013
  

Но приведенную выше таблицу мне нужно отобразить в 5 строк. Это означает преобразовать столбцы в строки пример ниже

 years | reg1 | reg2 | reg3 | reg4
------ ------ ------ ------ -----
 2016 | 6279 | 6641 | 8347 | NULL
 2015 | 6228 | 8596 | 7596 | 6352
 2014 | 1245 | 5248 | 6359 | 6785
 2013 | 9578 | 4398 | 2986 | 7296
  

Я пробовал использовать pivot и unpivot в соответствии с некоторым предложением, но все равно не получаю. Пожалуйста, помогите мне.

Ответ №1:

Вот один из способов динамического достижения с помощью CROSS TAB трюка

 DECLARE @sql      VARCHAR(max)='',
        @intr     INT = 1,
        @cnt      INT

SELECT @cnt = (SELECT ( Max([Years]) - Min([Years]) )   1
                     FROM   Yourtable)

SET @sql = 'select [Years], '

WHILE @intr <= @cnt
  BEGIN
      SET @sql  = 'max(case when rn = '  Cast(@intr AS VARCHAR(4))   ' then [reg] end) as [reg'
                    Cast(@intr AS VARCHAR (100))   '],'
      SET @intr =1
  END

SET @sql = LEFT(@sql, Len(@sql) - 1)

SELECT @sql  = 'from (select row_number()over(partition by [Years] order by [reg]) as rn,* from Yourtable) a group by [Years]'

--SELECT @sql

EXEC( @sql) 
  

Ответ №2:

Для ограниченного количества записей в год вы можете использовать условную агрегацию в статическом SQL-запросе:

 ;WITH temp_with_rn AS (
  SELECT eg, years, ROW_NUMBER() OVER (PARTITION BY Years ORDER BY eg) AS rn
  FROM temp
) 
SELECT years, 
       MAX(CASE WHEN rn = 1 THEN eg END) AS reg1,
       MAX(CASE WHEN rn = 2 THEN eg END) AS reg2,
       MAX(CASE WHEN rn = 3 THEN eg END) AS reg3,
       MAX(CASE WHEN rn = 4 THEN eg END) AS reg4
FROM temp_with_rn
GROUP BY years
  

Комментарии:

1. У меня есть одно сомнение… мы используем функцию Max() в запросе…. Если мы будем использовать этот максимум, он будет первым …. но мне не нужно.. пожалуйста, помогите мне … в другом решении

Ответ №3:

Использование PIVOT:

 Select * from
(Select *, 'reg'   cast(row_number() over(partition by year order by reg) as varchar(5)) RowVal
from table) x
PIVOT
(
MAX(reg) FOR RowVal in ([reg1], [reg2], [reg3], [reg4])
) y
order by year desc