2014-04-08 28 views
0

我有一个动态生成的表,我需要有所有列变为行变化列行

所以我的表看起来像这样

Conv1 | Conv2 | ... 
data1 | data2 | ... 
data1 | data2 | ... 
data1 | data2 | ... 
... | ... | ... 

,因为它是动态的,我不知道到底有多少行/列没有运行Select count(*)或类似的东西。

基本上我想要上表中可以改变这个

data1 | data1 | data1 | ... 
data2 | data2 | data2 | ... 
data3 | data3 | data3 | ... 
data4 | data4 | data4 | ... 

我看着使用Pivot但是我不知道我怎么会用它在这种情况下。

我正在使用SQL Server 2008 R2

任何帮助将不胜感激。让我知道你是否需要更多信息。

谢谢。

--update

这里是一个与“转化”项目作为列名的当前表结构。

Conv1 | Conv2 | Conv3 | ... 
data1 | data2 | data3 | ... 
data1 | data2 | data3 | ... 
data1 | data2 | data3 | ... 
... | ... | ... | ... 

这里的“数据”作品是varchar(250)

考虑数据会话(CONV1)的存储库和行是一系列的问题和答复。 因为我在与我的工作是什么性质不知道该“数据”的内容是一个问题,这是一个响应。

这就是我想要的结果看起来像:

 Col1 | Col2 | Col3 | ... 
Conv1 | data1 | data1 | data1 | ... 
Conv2 | data2 | data2 | data2 | ... 
Conv3 | data3 | data3 | data3 | ... 
Conv4 | data4 | data4 | data4 | ... 

如果这仍然没有足够的信息让我知道,我会看看还有什么我可以提供。

+0

这是执行动态旋转的方式: http://stackoverflow.com/a/11985946/3503205 – Ryx5

+0

你尝试过:HTTP:// stackoverflow.com/questions/15091330/sql-server-convert-columns-to-rows][1] [1]:http://stackoverflow.com/questions/15091330/sql-server-convert-columns- to-rows – lyosha

+0

我不明白我会用@代替@ Ryx5注释中的min(choice),或者@lyosha注释中的max(val)。或者对于这个问题真的是'Pivot'部分的内容。在所有示例中,我都看到原始表格中包含具有特定内容的列,在我的案例中,这些列基本上包含几乎相同类型的数据,但对它们没有真正的区别特征。 – shadonar

回答

1

你所要做的是一个完整的数据调换您的当前数据的列变为行,你的行变为列,这可以分两步来完成。首先,应用UNPIVOT功能转换的Conv1Conv2,等你当前列成行,那么在应用旋转功能的data1data2转换成列。

此前试图编写查询的动态版本,我总是用一个静态的版本启动,以便能得到正确的逻辑,然后转换为动态SQL。为了产生新的列名Col1Col2等查询数据时,我会用一个窗口函数像row_number(),这会为你要转的每一行数据的唯一序列。

的UNPIVOT代码将类似于:

;with cte as 
(
    select Conv1, Conv2, Conv3, 
     row_number() over(order by conv1) seq 
    from dbo.yourtable 
) 
select * 
from 
(
    select Conv, value, 
     col = 'Col'+cast(seq as varchar(50)) 
    from cte 
    unpivot 
    (
     value for Conv in (Conv1, Conv2, Conv3) 
    ) unpiv 
) src; 

SQL Fiddle with Demo。这些数据将是这样的:

| CONV | VALUE | COL | 
|-------|-------|------| 
| Conv1 | data1 | Col1 | 
| Conv2 | data2 | Col1 | 
| Conv3 | data3 | Col1 | 
| Conv1 | data1 | Col2 | 
| Conv2 | data2 | Col2 | 
| Conv3 | data3 | Col2 | 

你会发现,你现在必须为每个Conv1多行和你有一个新的列使用row_number()来创建新的列名。现在您可以使用PIVOT完成数据的旋转:

;with cte as 
(
    select Conv1, Conv2, Conv3, 
     row_number() over(order by conv1) seq 
    from dbo.yourtable 
) 
select Conv, Col1, Col2, Col3 
from 
(
    select Conv, value, 
     col = 'Col'+cast(seq as varchar(50)) 
    from cte 
    unpivot 
    (
     value for Conv in (Conv1, Conv2, Conv3) 
    ) unpiv 
) src 
pivot 
(
    max(value) 
    for col in (Col1, Col2, Col3) 
) piv; 

请参阅SQL Fiddle with Demo。这将完全转换您的当前数据到您的最终结果。对于你的情况你说你需要一个动态解决方案,所以你将需要使用动态SQL。这将涉及到越来越需要被逆转置列名,然后将新列的列表为枢轴:

DECLARE @colsUnpivot AS NVARCHAR(MAX), 
    @colsPivot AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @colsUnpivot = STUFF((SELECT ','+ quotename(c.name) 
        from sys.tables t 
        inner join sys.columns c 
         on t.object_id = c.object_id 
        where t.name = 'yourtable' 
        group by c.name, c.column_id 
        order by c.column_id 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

select @colsPivot = STUFF((SELECT ','+ quotename('Col'+cast(seq as varchar(10))) 
        from 
        (
        select row_number() over(order by conv1) seq 
        from dbo.yourtable 
        ) d 
        group by seq 
        order by seq 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query 
    = ';with cte as 
    (
     select Conv1, Conv2, Conv3, 
      row_number() over(order by conv1) seq 
     from dbo.yourtable 
    ) 
    select Conv, '[email protected]+' 
    from 
    (
     select Conv, value, 
      col = ''Col''+cast(seq as varchar(50)) 
     from cte 
     unpivot 
     (
      value for Conv in ('[email protected]+') 
     ) unpiv 
    ) src 
    pivot 
    (
     max(value) 
     for col in ('[email protected]+') 
    ) piv' 

execute sp_executesql @query; 

SQL Fiddle with Demo。这两个给出最终结果:

| CONV | COL1 | COL2 | COL3 | 
|-------|-------|-------|-------| 
| Conv1 | data1 | data1 | data1 | 
| Conv2 | data2 | data2 | data2 | 
| Conv3 | data3 | data3 | data3 |