Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.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 server中转换表_Sql_Sql Server_Pivot_Transpose - Fatal编程技术网

在SQL server中转换表

在SQL server中转换表,sql,sql-server,pivot,transpose,Sql,Sql Server,Pivot,Transpose,我正在为我的应用程序使用SQLServer2005。 我的存储过程中有一个表,它有两列,C1和C2。我想转置这个表,使列C1的值成为列。 转置前(表1): 转置后(表2): 在表1中,不同值(M1,M2)的数量可能不同。因此,表2中的列不是固定的 请提供一个解决方案来实现同样的目标。这可能是动态sql是您的朋友的情况。假设基表的名称为“转置”: 如果您的基表有一个键字段,则可以稍微修改查询,以按键字段对结果进行分组,并可能更接近您对结果数据的指定目标。这不是您想要的确切结果,但您可以尝试一下 对

我正在为我的应用程序使用SQLServer2005。 我的存储过程中有一个表,它有两列,C1和C2。我想转置这个表,使列C1的值成为列。 转置前(表1):

转置后(表2):

在表1中,不同值(M1,M2)的数量可能不同。因此,表2中的列不是固定的


请提供一个解决方案来实现同样的目标。

这可能是动态sql是您的朋友的情况。假设基表的名称为“转置”:

如果您的基表有一个键字段,则可以稍微修改查询,以按键字段对结果进行分组,并可能更接近您对结果数据的指定目标。

这不是您想要的确切结果,但您可以尝试一下
对于这种类型的数据转换,您需要使用SQL Server 2005+中提供的
PIVOT
函数。有两种方法可以应用pivot函数

如果您提前知道这些值,那么可以在查询中硬编码这些值。与此类似:

select M1, M2
from
(
  select c1, c2,
    row_number() over(partition by c1 order by c1, c2) rn
  from yourtable
) src
pivot
(
  max(c2)
  for c1 in (M1, M2)
) piv

但是,如果要将未知数量的值转换为列,则可以使用动态SQL在运行时创建查询

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(C1) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ' + @cols + ' from 
             (
                select C1, C2,
                  row_number() over(partition by c1 order by c1, c2) rn
                from yourtable
            ) x
            pivot 
            (
                max(C2)
                for C1 in (' + @cols + ')
            ) p '

execute(@query)

两者都会给出相同的结果,不同之处在于,如果值发生变化,动态版本是灵活的:

| M1 |     M2 |
---------------
| U1 |     U4 |
| U2 |     U5 |
| U3 | (null) |

用动态SQL查询PIVOT;这个问题以前已经回答过好几次了。Hey的可能重复Hey的可能重复谢谢你的回答…有没有办法在SQL中只对coulmn进行排序,这样其他所有列就不会被排序了。在excel中,我们可以这样做。我不知道SQL Server。如果有任何方法可以做到这一点,请提供帮助。提前谢谢。这是一个很好的解决方案,但是你能详细说明一下在这种情况下,
row_number()over(按c1顺序划分,按c1,c2)rn
的作用吗?@JeremyS。使用字符串值时,聚合选项仅限于
max
min
。因此,如果不使用
行编号
,您将只得到一行。带有
分区的
行编号
生成一个不同的值,该值在
分组过程中保持值之间的分隔。请看,如果没有<代码> RoWixNo.<代码>,你只得到一行。感谢这个例子,我看到了,仍然不明白MSSQL是如何考虑把代码> RooSoxNo.<代码>作为一个不同的值,它不包含在GROUPBY子句中,因为没有,为什么MSSQL知道?@ JeleMy.
PIVOT
正在执行聚合,而
group by
未明确说明正在使用。我建议阅读MSDN上的。或者,如果您有特定问题,请发布新问题。:)您好,您的转置对我非常有用,但我不能在mysql服务器5.1上使用它。我在开始时遇到了一个关于“声明”的错误。我能做些什么来完成这次跑步?
M1     M2      M3
U1     NULL    NULL
U2     NULL    NULL
U3     NULL    NULL
NULL   U4      NULL
NULL   U5      NULL
NULL   NULL    U6
;WITH TAB1 AS
( SELECT  [ResponsibleID] C1,[ActionID] C2,1 ORD
  FROM [TEST].[dbo].[yourtable]
  WHERE 1=1
  )


 SELECT 
    CASE WHEN M1=1 THEN ActionID ELSE NULL END M1,
    CASE WHEN M2=1 THEN ActionID ELSE NULL END M2 
 FROM TAB1
 PIVOT(AVG(ORD) FOR RESPONSIBLEID IN ([M1],[M2])) AS ABC
select M1, M2
from
(
  select c1, c2,
    row_number() over(partition by c1 order by c1, c2) rn
  from yourtable
) src
pivot
(
  max(c2)
  for c1 in (M1, M2)
) piv
DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(C1) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ' + @cols + ' from 
             (
                select C1, C2,
                  row_number() over(partition by c1 order by c1, c2) rn
                from yourtable
            ) x
            pivot 
            (
                max(C2)
                for C1 in (' + @cols + ')
            ) p '

execute(@query)
| M1 |     M2 |
---------------
| U1 |     U4 |
| U2 |     U5 |
| U3 | (null) |