Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将列更改为行_Sql_Sql Server_Pivot - Fatal编程技术网

Sql 将列更改为行

Sql 将列更改为行,sql,sql-server,pivot,Sql,Sql Server,Pivot,我有一个动态生成的表,需要将所有列都更改为行 我的桌子看起来像这样 Conv1 | Conv2 | ... data1 | data2 | ... data1 | data2 | ... data1 | data2 | ... ... | ... | ... 因为它是动态的,如果不运行selectcount(*)或类似的操作,我不知道有多少行/列 基本上我想把上面的表格改成这个 data1 | data1 | data1 | ... data2 | data2 | data2 | ..

我有一个动态生成的表,需要将所有列都更改为行

我的桌子看起来像这样

Conv1 | Conv2 | ...
data1 | data2 | ...
data1 | data2 | ...
data1 | data2 | ...
 ...  |  ...  | ...
因为它是动态的,如果不运行
selectcount(*)
或类似的操作,我不知道有多少行/列

基本上我想把上面的表格改成这个

data1 | data1 | data1 | ...
data2 | data2 | data2 | ...
data3 | data3 | data3 | ...
data4 | data4 | data4 | ...
我研究了如何使用
Pivot
,但是我不确定在这种情况下如何使用它

我正在使用SQL Server 2008 R2

任何帮助都将不胜感激。如果你需要更多的信息,请告诉我

多谢各位

--更新

以下是当前的表结构,其中“Conv”项作为列名

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 | ...
|  CONV | VALUE |  COL |
|-------|-------|------|
| Conv1 | data1 | Col1 |
| Conv2 | data2 | Col1 |
| Conv3 | data3 | Col1 |
| Conv1 | data1 | Col2 |
| Conv2 | data2 | Col2 |
| Conv3 | data3 | Col2 |

如果这还不够,请告诉我,我会看看我还能提供什么。

您试图做的是一个完整的数据转换,当前数据列变成行,行变成列,这可以通过两个步骤完成。首先,应用UNPIVOT函数将当前的
Conv1
Conv2
等列转换为行,然后应用PIVOT函数将
data1
data2
转换为列

在尝试编写查询的动态版本之前,我总是从静态版本开始,以便获得正确的逻辑,然后转换为动态sql。为了生成新列名
Col1
Col2
等,我会在查询数据时使用类似
row\u 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;
看。数据如下所示:

        Col1  | Col2  | Col3  | ...
Conv1 | data1 | data1 | data1 | ...
Conv2 | data2 | data2 | data2 | ...
Conv3 | data3 | data3 | data3 | ...
Conv4 | data4 | data4 | data4 | ...
|  CONV | VALUE |  COL |
|-------|-------|------|
| Conv1 | data1 | Col1 |
| Conv2 | data2 | Col1 |
| Conv3 | data3 | Col1 |
| Conv1 | data1 | Col2 |
| Conv2 | data2 | Col2 |
| Conv3 | data3 | Col2 |
您会注意到,现在每个
Conv1
都有多行,并且有一个新列,它使用
row\u 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。这将涉及获取需要取消pivot的列名列表,然后获取pivot的新列:

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, '+@colsPivot+'
    from 
    (
        select Conv, value, 
            col = ''Col''+cast(seq as varchar(50))
        from cte
        unpivot
        (
            value for Conv in ('+@colsUnpivot+')
        ) unpiv
    ) src
    pivot
    (
        max(value)
        for col in ('+@colsPivot+')
    ) piv'

execute sp_executesql @query;
看。两者都给出了以下最终结果:

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

以下是执行动态透视的方法:您是否尝试过:[[1]:我不明白我将使用什么来替换@Ryx5 comment中的
min(choice)
,或
max(val)
在@lyosha comment中。或者实际上,
Pivot
部分中会有什么内容。在所有示例中,我看到原始表中有具有特定内容的列,在我的示例中,这些列包含几乎相同类型的数据,没有真正的区别特征。我假设使用
Pivot
这不是答案,因为我不认为我真的有什么可以“聚合”的东西,从我慢慢了解的情况来看,这是
Pivot
工作所必需的。是否有其他方法将列转换为行?我想我只需将内容转储到Excel文件中,并使用它的“转置”功能。