规范化数据库(按列分列)

时间:2017-03-14 10:07:33

标签: sql sql-server normalize

我有一个连接到SQL(PERVASIVE)的表,每个月输出一列。 为了在Excel中更好地工作,我需要将12列转换为仅2 ... - 价值观的第一个; - 相应月份的第二个月(此时,月份是列标题)。

示例,转换当前数据库结构:

Al_Cta     | MoedCod | TpVal   | FlagDC  | Month01 | Month02 | Month03
AAAAA      |     100 |      20 |        5|      15 |      18 |      16
BBBBB      |     200 |      40 |       10|      20 |      21 |      26
CCCCC      |     300 |      60 |       15|      40 |      48 |      41

理想的输出:

Al_Cta     |  MoedCod|TpVal | FlagDC  | Value   | Month
AAAAA      |     100 |    20|       5 |      15 |     01
AAAAA      |     100 |    20|       5 |      18 |     02
AAAAA      |     100 |    20|       5 |      16 |     03
BBBBB      |     200 |    40|      10 |      20 |     01
BBBBB      |     200 |    40|      10 |      21 |     02
BBBBB      |     200 |    40|      10 |      26 |     03
CCCCC      |     300 |    60|      15 |      40 |     01
CCCCC      |     300 |    60|      15 |      48 |     02
CCCCC      |     300 |    60|      15 |      41 |     03

我已经在论坛上得到了一些帮助,但我没有设法做到这一点。 我使用以下命令,但数据库根本就没有改变,有人可以看到有什么问题吗?

SELECT * 
  FROM [IN16-CTAVAL]
Select p.Al_Cta ,MoedCod ,TpVal,FlagDC, 
       sale_quantity ,salemonths
  From products as p 
     inner join (    
         Select Al_Cta  ,sale_quantity ,salemonths from products
           UNPIVOT
      (
         salemonths for sale_quantity in (Month01 | Month02 | Month03) 
      )) as pp on p.Al_Cta = pp.Al_Cta

最好的问候!!!

1 个答案:

答案 0 :(得分:1)

select al_cta,
moedcod,
tpval,
flagdc,b.*
 from maintable
 cross apply
( 
values
 (month01,'01') ,
 (month02,'02') ,
 (month03,'03')
  ) 
 b(value,month)

如果您有更多列,则可以在values子句中添加更多列。

上面代码的工作方式是

cross apply可以访问主表行,并将它们转换为如下所示的列

values
(a,b),--row with two columns
(c,d)

所以上面的代码将针对主表中的每一行进行评估,它将是主表r1中的行的产品和值子句的输出。如下所示

Row1* value clause row1
Row1* value clause row2
Row1* value clause row3

and so  on