2014-01-05 5 views
0

У меня есть 3 столбца в SQL - Имя, ID и Период:Сводные столбцы в SQL Server

Name CarID Period 
--------------------- 
Bob  121  Jan 08 
Bob  123  Jan 08 
Bob  121  Feb 08 
Steve 121  Jan 08 
Ruth 139  Feb 08 

мне нужно повернуть CarID вместе уникальное имя и период, то есть:

Name Period Col1 Col2 Col3 
------------------------------------- 
Bob  Jan 08 121  123 NULL 
Bob  Feb 08 121  NULL NULL 
Steve Jan 08 121  NULL NULL 
Ruth Feb 08 139  NULL NULL 

Мои проблема в том, что у именованного пользователя может быть 1 или x число CarID's против их имени. Я пробовал несколько динамических сводных запросов, но всем им нужно было установить имена заголовков столбцов.

+0

Вы ищете «кросс-таблицу». См. Http://www.postgresql.org/docs/9.3/static/tablefunc.html – maybeWeCouldStealAVan

+0

Глядя на это, кажется, вам нужно знать, сколько столбцов вам понадобится? –

+0

@bluefeet Неисправность мозга с моей стороны - я видел тег Postgresql, которого там не было. – maybeWeCouldStealAVan

ответ

1

Есть несколько способов, которые вы можете получить результат, который вы хотите, но для того, чтобы успешно возвращать несколько carid значения для каждого name и period, я хотел бы использовать оконную функцию как row_number() генерировать уникальную последовательность для каждого раздела name/period.

Ваш запрос будет начинаться с помощью что-то вроде:

select name, carid, period, 
    'col'+ 
    cast(row_number() over(partition by name, period 
          order by carid) as varchar(10)) seq 
from yourtable; 

См SQL Fiddle with Demo. Это даст вам следующие данные, которые вы можете затем PIVOT в столбцы.

| NAME | CARID | PERIOD | SEQ | 
|-------|-------|--------|------| 
| Bob | 121 | Feb 08 | col1 | 
| Bob | 121 | Jan 08 | col1 | 
| Bob | 123 | Jan 08 | col2 | 
| Ruth | 139 | Feb 08 | col1 | 
| Steve | 121 | Jan 08 | col1 | 

Вы можете преобразовать эти данные в столбцы, используя агрегатную функцию и выражение CASE, похожее на:

select 
    name, 
    period, 
    max(case when seq = 'col1' then carid end) col1, 
    max(case when seq = 'col2' then carid end) col2, 
    max(case when seq = 'col3' then carid end) col3 
from 
(
    select name, carid, period, 
    'col'+ 
     cast(row_number() over(partition by name, period 
           order by carid) as varchar(10)) seq 
    from yourtable 
) d 
group by name, period; 

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

select name, period, col1, col2, col3 
from 
(
    select name, carid, period, 
    'col'+ 
     cast(row_number() over(partition by name, period 
           order by carid) as varchar(10)) seq 
    from yourtable 
) d 
pivot 
(
    max(carid) 
    for seq in (col1, col2, col3) 
) p; 

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

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

select @cols = STUFF((SELECT ',' + QUOTENAME(seq) 
        from 
        (
         select 'col'+ 
          cast(row_number() over(partition by name, period 
                order by carid) as varchar(10)) seq 
         from yourtable 
        ) d 
        group by seq 
        order by seq 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT name, period,' + @cols + ' 
      from 
      (
       select name, carid, period, 
       ''col''+ 
        cast(row_number() over(partition by name, period 
              order by carid) as varchar(10)) seq 
       from yourtable 
      ) x 
      pivot 
      (
       max(carid) 
       for seq in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

См SQL Fiddle with Demo. Все версии дадут вам результат, аналогичный:

| NAME | PERIOD | COL1 | COL2 | 
|-------|--------|------|--------| 
| Bob | Feb 08 | 121 | (null) | 
| Ruth | Feb 08 | 139 | (null) | 
| Bob | Jan 08 | 121 | 123 | 
| Steve | Jan 08 | 121 | (null) | 
Смежные вопросы