Несколько столбцов Pivot в T-SQL - PullRequest
14 голосов
/ 04 июня 2009

Я работаю с таблицей, в которой есть несколько строк, которые мне нужно развернуть в столбцы. Таким образом, стержень является идеальным решением для этого, и работает хорошо, когда все, что мне нужно, это одно поле. Мне нужно вернуть несколько полей на основе пивота. Вот псевдокод со спецификой:

SELECT 
  field1,
  [1], [2], [3], [4]
FROM
  (
  SELECT 
    field1, 
    field2, 
    (ROW_NUMBER() OVER(PARTITION BY field1 ORDER BY field2)) RowID
  FROM tblname
  ) AS SourceTable
PIVOT
  (
  MAX(field2)
  FOR RowID IN ([1], [2], [3], [4])
  ) AS PivotTable;

Приведенный выше синтаксис работает превосходно, но что мне делать, когда мне нужно получить дополнительную информацию в field3, field4 ....?

Ответы [ 5 ]

12 голосов
/ 04 июня 2009

Переписать, используя MAX (CASE ...) и GROUP BY:

select 
  field1
, [1] = max(case when RowID = 1 then field2 end)
, [2] = max(case when RowID = 2 then field2 end)
, [3] = max(case when RowID = 3 then field2 end)
, [4] = max(case when RowID = 4 then field2 end)
from (
  select 
    field1
  , field2
  , RowID = row_number() over (partition by field1 order by field2)
  from tblname
  ) SourceTable
group by 
  field1

Оттуда вы можете добавить в field3, field4 и т. Д.

2 голосов
/ 29 октября 2012

Хитрость в выполнении нескольких сводок по номеру row_number состоит в том, чтобы изменить последовательность номеров строк, чтобы сохранить как последовательность, так и номер поля. Вот пример, который делает то, что вы хотите с несколькими операторами PIVOT.

-- populate some test data
if object_id('tempdb..#tmp') is not null drop table #tmp
create table #tmp (
    ID int identity(1,1) not null,
    MainField varchar(100),
    ThatField int,
    ThatOtherField datetime
)

insert into #tmp (MainField, ThatField, ThatOtherField)
select 'A', 10, '1/1/2000' union all
select 'A', 20, '2/1/2000' union all
select 'A', 30, '3/1/2000' union all
select 'B', 10, '1/1/2001' union all
select 'B', 20, '2/1/2001' union all
select 'B', 30, '3/1/2001' union all
select 'B', 40, '4/1/2001' union all
select 'C', 10, '1/1/2002' union all
select 'D', 10, '1/1/2000' union all
select 'D', 20, '2/1/2000' --union all

-- pivot over multiple columns using the 1.1, 1.2, 2.1, 2.2 sequence trick
select
    MainField,
    max([1.1]) as ThatField1,
    max([1.2]) as ThatOtherField1,
    max([2.1]) as ThatField2,
    max([2.2]) as ThatOtherField2,
    max([3.1]) as ThatField3,
    max([3.2]) as ThatOtherField3,
    max([4.1]) as ThatField4,
    max([4.2]) as ThatOtherField4
from
    (
        select x.*,
            cast(row_number() over (partition by MainField order by ThatField) as varchar(2)) + '.1' as ThatFieldSequence,
            cast(row_number() over (partition by MainField order by ThatField) as varchar(2)) + '.2' as ThatOtherFieldSequence
        from #tmp x
    ) a
    pivot (
        max(ThatField) for ThatFieldSequence in ([1.1], [2.1], [3.1], [4.1])
    ) p1
    pivot (
        max(ThatOtherField) for ThatOtherFieldSequence in ([1.2], [2.2], [3.2], [4.2])
    ) p2
group by
    MainField
1 голос
/ 19 сентября 2010

оберните ваш SQL-запрос что-то вроде:

select a.segment, sum(field2), sum(field3) 
from (original select with case arguments) a
group by a.segment

Он должен свести ваши результаты в один ряд, сгруппированный по полю 1.

1 голос
/ 04 июня 2009

Я не уверен, что вы используете MS SQL Server, но если вы ... Возможно, вы захотите взглянуть на функциональность CROSS APPLY движка. В основном это позволит вам применить результаты табличного UDF к набору результатов. Для этого потребуется поместить сводный запрос в набор результатов с табличным значением.

http://weblogs.sqlteam.com/jeffs/archive/2007/10/18/sql-server-cross-apply.aspx

0 голосов
/ 05 марта 2012

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

http://pratchev.blogspot.com/2009/01/pivoting-on-multiple-columns.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...