SQL Server:Pivot和unpivots

Cal*_*r99 0 sql sql-server pivot

我正试图调整这个SQL Server表,但是我很难绕过我需要做的事情.我可以做一个基本的支点,但这已经变得非常具有挑战性.我本质上是将下表转换为

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我计划在一个数据集和一个列上,然后将表连接到自身,再次执行另一个数据库,但我没有捕获列名.任何建议将不胜感激.

Tar*_*ryn 7

你的想法是正确的,你需要unpivot先得到你想要的最终结果.您需要将您的多列Billings,CollectionsDebtors在为多行,然后转动Period值代入列.

您没有指定您正在使用的SQL Server版本,但从SQL Server 2005开始,您可以使用CROSS APPLY以取消:

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);
Run Code Online (Sandbox Code Playgroud)

演示.这会将您的数据转换为以下格式:

| 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 |
Run Code Online (Sandbox Code Playgroud)

您会注意到现在每个都有一行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;
Run Code Online (Sandbox Code Playgroud)

请参阅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 |
Run Code Online (Sandbox Code Playgroud)

现在,如果你有一个的可能性CompanyCodeAccountClass可能出现多次的相同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;
Run Code Online (Sandbox Code Playgroud)

请参阅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) |
Run Code Online (Sandbox Code Playgroud)