2013-11-07 9 views
0

Я попытался выполнить несколько других предложений на этом веб-сайте, но по какой-то причине не смог бы это сделать.Подведение нескольких столбцов на основе одной колонки

В основном я пытаюсь получить из этой таблицы задач:

| TaskID | ProjectID | TaskType | TaskDate1 | TaskDate2 | 
--------------------------------------------------------- 
|  1 |   1 | Type4 | 20130401 | 20130506 | 
|  2 |   1 | Type0 | 20130412 | 20130508 | 
|  3 |   1 | Type2 | 20130420 | 20130517 | 

к тому, что один:

| ProjectID | Type0Date1 | Type0Date2 | Type2Date1 | Type2Date2 | Type4Date1 | Type4Date2 | 
--------------------------------------------------------- 
|   1 | 20130412 | 20130508 | 20130420 | 20130517 | 20130401 | 20130506 | 

Каждый проект должен иметь каждый из нескольких предопределенных задач (идентифицируются по их типу). Эти задачи имеют много свойств, но меня интересуют две даты, и было бы неплохо привести их всех в одну строку для каждого проекта.

можно легко поворачивать его на одной из колонн с: PIVOT (MAX(TaskDate1) FOR TaskType IN ([Type0],[Type2],[Type4]))

Я пытался дублировать столбец TaskType и делает еще один стержень вокруг него для TaskDate2, но это не даст мне одну строку.

Я также не могу окутать голову в то, как первая таблица будет открыта мне, где я должен быть, как это было предложено в некоторых других сообщениях по подобным вопросам.

Если есть масштабируемый способ сделать это (как в случае поворота еще большего количества столбцов), было бы хорошо знать.

Спасибо.

ответ

1

Вы можете получить желаемый результат, но так как вам нужно PIVOT на несколько столбцов (и TaskDate2), я бы сначала разделил два столбца на несколько строк.

Поскольку вы используете SQL Server 2008+, вы можете использовать функцию UNPIVOT или CROSS APPLY для преобразования нескольких столбцов. Основным синтаксисом будет:

select projectid, 
    col = TaskType+col, 
    value 
from yourtable 
cross apply 
(
    values 
    ('Date1', TaskDate1), 
    ('Date2', TaskDate2) 
) c(col, value) 

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

| PROJECTID |  COL |      VALUE | 
|-----------|------------|------------------------------| 
|   1 | Type4Date1 | April, 01 2013 00:00:00+0000 | 
|   1 | Type4Date2 | May, 06 2013 00:00:00+0000 | 
|   1 | Type0Date1 | April, 12 2013 00:00:00+0000 | 
|   1 | Type0Date2 | May, 08 2013 00:00:00+0000 | 

После того, как у вас есть данные в таком формате, то вы можете применить функцию PIVOT к ПОЛУЧАТ max(value) для каждого col:

select projectId, 
    Type0Date1, Type0Date2, 
    Type2Date1, Type2Date2, 
    Type4Date1, Type4Date2 
from 
(
    select projectid, 
    col = TaskType+col, 
    value 
    from yourtable 
    cross apply 
    (
    values 
     ('Date1', TaskDate1), 
     ('Date2', TaskDate2) 
) c(col, value) 
) d 
pivot 
(
    max(value) 
    for col in (Type0Date1, Type0Date2, Type2Date1, Type2Date2, 
       Type4Date1, Type4Date2) 
) piv; 

См. SQL Fiddle with Demo.

выше версия будет работать хорошо, если у вас есть ограниченное количество значений в ProjectId, но если у вас есть неизвестное количество задач для каждого проекта, то вам необходимо будет использовать динамический SQL, чтобы получить конечный результат:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(TaskType+col) 
        from yourtable 
        cross apply 
        (
         select 'Date1', 1 union all 
         select 'Date2', 2 
        ) c(col, so) 
        group by col, tasktype, so 
        order by tasktype, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT projectid, ' + @cols + ' 
      from 
      (
       select projectid, 
       col = TaskType+col, 
       value 
       from yourtable 
       cross apply 
       (
       values 
        (''Date1'', TaskDate1), 
        (''Date2'', TaskDate2) 
      ) c(col, value) 
      ) x 
      pivot 
      (
       max(value) 
       for col in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query 

См. SQL Fiddle with Demo. Они приведут к следующему:

| PROJECTID |     TYPE0DATE1 |     TYPE0DATE2 |     TYPE2DATE1 |     TYPE2DATE2 |     TYPE4DATE1 |     TYPE4DATE2 | 
|-----------|------------------------------|----------------------------|------------------------------|----------------------------|------------------------------|----------------------------| 
|   1 | April, 12 2013 00:00:00+0000 | May, 08 2013 00:00:00+0000 | April, 20 2013 00:00:00+0000 | May, 17 2013 00:00:00+0000 | April, 01 2013 00:00:00+0000 | May, 06 2013 00:00:00+0000 | 
Смежные вопросы