2013-08-26 2 views
-2

У меня есть данные в таблице SQLServer, как это:Простой SQL Query -

ID Name Year Value 
-- ---- ---- ----- 
2 Ted 2013 2000 
2 Ted 2012 1000 

мне нужен синтаксис вида для вывода этого:

ID Name Yr1 Value1 Yr2 Value2 
-- ---- --- ------ --- ------ 
2  Ted  2013 2000  2012 1000 

если возможно нет курсоров. Любые подсказки были бы замечательными.

+1

Может быть полезно: [Использование PIVOT и UNPIVOT] (http://technet.microsoft.com/en-us/library/ms177410 (v = sql.105) .aspx) –

+0

Вы будете ограничены двумя годами в своем результате? – Taryn

ответ

3

В SQL Server существует несколько способов получить результат.

Если у вас ограниченное количество значений, вы можете легко скорректировать результат. Один из способов, вы можете получить результат будет использовать агрегатную функцию с выражением CASE-:

select d.id, 
    d.name, 
    max(case when seq = 1 then year end) year1, 
    max(case when seq = 1 then value end) value1, 
    max(case when seq = 2 then year end) year2, 
    max(case when seq = 2 then value end) value2 
from 
(
    select id, name, year, value, 
    row_number() over(partition by id order by year desc) seq 
    from yourtable 
) d 
group by d.id, d.name; 

См SQL Fiddle with Demo. Если вы хотите использовать функцию PIVOT, тогда я бы предложил сначала , не считая данных в столбцах year и . Процесс univot преобразует несколько столбцов в несколько строк. Вы можете использовать функцию UNPIVOT, но в моем примере я использовал CROSS ОТНОСИТЬСЯ с UNION ALL запрос и код:

select t.id, t.name, 
    col = c.col+cast(seq as varchar(4)), 
    c.val 
from 
(
    select id, name, year, value, 
    row_number() over(partition by id order by year desc) seq 
    from yourtable 
) t 
cross apply 
(
    select 'year', t.year union all 
    select 'value', t.value 
) c (col, val) 

См SQL Fiddle with Demo. Это преобразует несколько столбцов в несколько ином формате с несколькими строками:

| ID | NAME | COL | VAL | 
| 2 | Ted | year1 | 2013 | 
| 2 | Ted | value1 | 2000 | 
| 2 | Ted | year2 | 2012 | 
| 2 | Ted | value2 | 1000 | 

Вы можете применить функцию PIVOT на это, чтобы получить конечный желаемый результат:

select id, name, year1, value1, year2, value2 
from 
(
    select t.id, t.name, 
    col = c.col+cast(seq as varchar(4)), 
    c.val 
    from 
    (
    select id, name, year, value, 
     row_number() over(partition by id order by year desc) seq 
    from yourtable 
) t 
    cross apply 
    (
    select 'year', t.year union all 
    select 'value', t.value 
) c (col, val) 
) d 
pivot 
(
    max(val) 
    for col in (year1, value1, year2, value2) 
) piv; 

SQL Fiddle with Demo См. Наконец, если у вас есть неизвестное количество значений, которые вы хотите преобразовать из строк в столбцы, то вы можете использовать динамический SQL внутри хранимой процедуры:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(seq as varchar(4))) 
        from 
        (
         select row_number() over(partition by id order by year desc) seq 
         from yourtable 
        ) d 
        cross apply 
        (
         select 'year', 1 union all 
         select 'value', 2 
        ) c (col, so) 
        group by seq, col, so 
        order by seq, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 


set @query = 'SELECT id, name,' + @cols + ' 
      from 
      (
       select t.id, t.name, 
        col = c.col+cast(seq as varchar(4)), 
        c.val 
       from 
       (
        select id, name, year, value, 
        row_number() over(partition by id order by year desc) seq 
        from yourtable 
       ) t 
       cross apply 
       (
        select ''year'', t.year union all 
        select ''value'', t.value 
       ) c (col, val) 
      ) x 
      pivot 
      (
       max(val) 
       for col in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

См SQL Fiddle with Demo. Все версии будут давать результат:

| ID | NAME | YEAR1 | VALUE1 | YEAR2 | VALUE2 | 
| 2 | Ted | 2013 | 2000 | 2012 | 1000 | 
+0

Спасибо, голубой! – kanderson