2014-09-02 2 views
0

Я пытаюсь развернуть эту таблицу SQL Server, однако я изо всех сил пытаюсь обвести вокруг себя то, что мне нужно сделать. Я могу сделать базовый стержень, однако это стало очень сложным. Я, в сущности, чтобы преобразовать таблицу нижеSQL Server: Pivot and unpivots

Company Code Account Class   Period Billings Collections Debtors 
-------------------------------------------------------------------------------- 
500    Accounts Receiveable 1  xx   xx   xx 
500    Accounts Receiveable 2  xxx   xx   xx 
500    Accounts Receiveable 3  xx   xx   xxx 
500    Accounts Receiveable 1  xx   xx   xx 

в

Company Code  Account Class        1 2 3 
-------------------------------------------------------------------------- 
500    Accounts Receiveable  Billings  xx xx xx 
500    Accounts Receiveable  Collections xxx xx xx 
500    Accounts Receiveable  Debtors  xx xx xxx 

Я планировал к развороту и на одной колонке, а затем присоединиться к таблице с самим собой, выполняя другой стержень снова но я не фиксирую имя столбца. Любые предложения будут высоко ценится.

+1

@Bluefeet: PIVOT вопрос! :-) –

+3

@marc_s Вы позвонили? :) – Taryn

ответ

7

Ваше мнение, что вам нужно будет unpivot, чтобы получить конечный результат, который вы хотите. Вам нужно будет преобразовать несколько столбцов из Billings, Collections и Debtors в несколько строк, а затем повернуть значения Period в столбцы.

Вы не указали, какая версия SQL Server вы используете, но, начиная с SQL Server 2005 можно использовать CROSS APPLY для UNPIVOT:

select 
    CompanyCode, 
    AccountClass, 
    period, 
    [Type], 
    Value 
from yourtable t 
cross apply 
(
    select 'Billings', Billings union all 
    select 'Collections', Collections union all 
    select 'Debtors', Debtors 
) c ([Type], value); 

См Demo. Это превращает ваши данные в формате:

| COMPANYCODE |   ACCOUNTCLASS | PERIOD |  TYPE | VALUE | 
|-------------|----------------------|--------|-------------|-------| 
|   500 | Accounts Receiveable |  1 | Billings | xx | 
|   500 | Accounts Receiveable |  1 | Collections | xx | 
|   500 | Accounts Receiveable |  1 |  Debtors | xx | 
|   500 | Accounts Receiveable |  2 | Billings | xxx | 
|   500 | Accounts Receiveable |  2 | Collections | xx | 

Вы заметите, что теперь у вас есть строка для каждого Billings, Collections и Debtors. Теперь вы можете применить функцию PIVOT к Period колонке:

select 
    CompanyCode, 
    AccountClass, 
    Type, 
    [1], 
    [2], 
    [3] 
from 
(
    select 
    CompanyCode, 
    AccountClass, 
    period, 
    [Type], 
    Value 
    from yourtable t 
    cross apply 
    (
    select 'Billings', Billings union all 
    select 'Collections', Collections union all 
    select 'Debtors', Debtors 
) c ([Type], value) 
) unp 
pivot 
(
    max(value) 
    for period in ([1], [2], [3]) 
) piv; 

См SQL Fiddle with Demo. Это дает вам результат:

| COMPANYCODE |   ACCOUNTCLASS |  TYPE | 1 | 2 | 3 | 
|-------------|----------------------|-------------|----|-----|-----| 
|   500 | Accounts Receiveable | Billings | xx | xxx | xx | 
|   500 | Accounts Receiveable | Collections | xx | xx | xx | 
|   500 | Accounts Receiveable |  Debtors | xx | xx | xxx | 

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

select 
    CompanyCode, 
    AccountClass, 
    Type, 
    [1], 
    [2], 
    [3] 
from 
(
    select 
    CompanyCode, 
    AccountClass, 
    seq, 
    period, 
    [Type], 
    Value 
    from 
    (
    select CompanyCode, AccountClass, Period, Billings, 
     Collections, Debtors, 
     seq = row_number() over(partition by CompanyCode, AccountClass, Period 
           order by CompanyCode, AccountClass) 
    from yourtable 
) t 
    cross apply 
    (
    select 'Billings', Billings union all 
    select 'Collections', Collections union all 
    select 'Debtors', Debtors 
) c ([Type], value) 
) unp 
pivot 
(
    max(value) 
    for period in ([1], [2], [3]) 
) piv; 

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

| COMPANYCODE |   ACCOUNTCLASS |  TYPE | 1 |  2 |  3 | 
|-------------|----------------------|-------------|----|--------|--------| 
|   500 | Accounts Receiveable | Billings | xx | xxx |  xx | 
|   500 | Accounts Receiveable | Collections | xx |  xx |  xx | 
|   500 | Accounts Receiveable |  Debtors | xx |  xx | xxx | 
|   500 | Accounts Receiveable | Billings | xx | (null) | (null) | 
|   500 | Accounts Receiveable | Collections | xx | (null) | (null) | 
|   500 | Accounts Receiveable |  Debtors | xx | (null) | (null) | 
+0

Смотрите - вы знаете ответ! :-) –

+0

Ничего себе, что является чрезвычайно всеобъемлющим. К сожалению, когда я пытаюсь применить свой метод, я получаю ошибки. Мне придется еще больше углубиться в это. – Calgar99

+0

@ Calgar99 Какая у вас ошибка? Какую версию SQL Server вы используете? – Taryn

1

Попробуйте следующее. Сначала вам понадобится UNPIVOT Billings, Collections и Debtors, затем PIVOT Period.

declare @table table 
    ([CompanyCode] int, [AccountClass] varchar(20), [Period] int, [Billings] varchar(3), [Collections] varchar(3), [Debtors] varchar(3)); 

INSERT INTO @table 
    ([CompanyCode], [AccountClass], [Period], [Billings], [Collections], [Debtors]) 
VALUES 
    (500, 'Accounts Receiveable', 1, 'xx', 'xx', 'xx'), 
    (500, 'Accounts Receiveable', 2, 'xxx', 'xx', 'xx'), 
    (500, 'Accounts Receiveable', 3, 'xx', 'xx', 'xxx'), 
    (500, 'Accounts Receiveable', 1, 'xx', 'xx', 'xx'); 

SELECT * 
    FROM (
     SELECT [CompanyCode], [AccountClass], [Period], [Type], [Value] 
     FROM @table 
     UNPIVOT ([Value] FOR [Type] IN ([Billings],[Collections],[Debtors])) AS u 
     ) as t 
    PIVOT (MAX(Value) FOR [Period] IN ([1], [2], [3])) AS pvt; 
    -- use SUM(Value) if Billings/Collections/Debtors are numeric columns 

ВЫВОД

CompanyCode AccountClass   Type   1 2 3 
----------- -------------------- ------------ ---- ---- ---- 
500   Accounts Receiveable Billings  xx xxx xx 
500   Accounts Receiveable Collections xx xx xx 
500   Accounts Receiveable Debtors  xx xx xxx