Sql server 在不聚合的情况下转置SQL Server表
我有一个SQL Server表,我想转置它,即切换行和列 原始表如下所示:Sql server 在不聚合的情况下转置SQL Server表,sql-server,Sql Server,我有一个SQL Server表,我想转置它,即切换行和列 原始表如下所示: empname empqual emprank empexp Lily MASTERS 1 9 Sasha UNIVERSITY 1 9 Harry UNIVERSITY 1 9 Angela MASTERS 4 10 Joyce
empname empqual emprank empexp
Lily MASTERS 1 9
Sasha UNIVERSITY 1 9
Harry UNIVERSITY 1 9
Angela MASTERS 4 10
Joyce UNIVERSITY 5 11
DETAILS Column1 Column2 Column3 Column4 Column5
empname Lily Sasha Harry Angela Joyce
empqual MASTERS UNIVERSITY UNIVERSITY MASTERS UNIVERSITY
emprank 1 1 1 4 5
empexp 9 9 9 10 11
请注意,行数据是动态的,上表只是为了演示表模式
编辑:我想修改上表,使其看起来像这样:
empname empqual emprank empexp
Lily MASTERS 1 9
Sasha UNIVERSITY 1 9
Harry UNIVERSITY 1 9
Angela MASTERS 4 10
Joyce UNIVERSITY 5 11
DETAILS Column1 Column2 Column3 Column4 Column5
empname Lily Sasha Harry Angela Joyce
empqual MASTERS UNIVERSITY UNIVERSITY MASTERS UNIVERSITY
emprank 1 1 1 4 5
empexp 9 9 9 10 11
我已经浏览了几个在线示例。在对表进行转置时,PIVOT
函数似乎是最常用的函数,但是由于我需要的操作不涉及任何聚合,与大多数其他示例不同,我不知道如何执行此操作。如果此问题多余且其他地方已有可能的答案,则表示歉意。您可以在此处查看
编辑
我让它充满活力
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
SET @cols = STUFF((SELECT distinct ',' + 'Column' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname))
FROM Table1 c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = '
SELECT 1 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empname) as e,
''empname'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 2 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empqual) as e,
''empqual'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 3 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,emprank) as e,
''emprank'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 4 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empexp) as e,
''empexp'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
order by OrderBy'
EXECUTE (@query)
詹尼斯您可以在这里查看
编辑
我让它充满活力
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
SET @cols = STUFF((SELECT distinct ',' + 'Column' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname))
FROM Table1 c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = '
SELECT 1 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empname) as e,
''empname'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 2 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empqual) as e,
''empqual'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 3 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,emprank) as e,
''emprank'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 4 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empexp) as e,
''empexp'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
order by OrderBy'
EXECUTE (@query)
Giannis此查询适用于您的样本数据:
declare @t table(
empname varchar(20) not null,
empqual varchar(20) not null,
emprank int not null,
empexp int not null
)
insert into @t(empname,empqual,emprank,empexp) values
('Lily','MASTERS',1,9),
('Sasha','UNIVERSITY',1,9),
('Harry','UNIVERSITY',1,9),
('Angela','MASTERS',4,10),
('Joyce','UNIVERSITY',5,11)
select *
from (select empname,empqual,CONVERT(varchar(20),emprank) as emprank,CONVERT(varchar(20),empexp) as empexp from @t) t
unpivot (value FOR measure in (empqual,emprank,empexp)) as unpvt
pivot (MAX(value) for empname in (Lily,Sasha,Harry,Angela,Joyce)) pvt
order by
CASE measure WHEN 'empqual' THEN 0
WHEN 'emprank' THEN 1
WHEN 'empexp' THEN 2
END
结果:
measure Lily Sasha Harry Angela Joyce
------------ -------------------- -------------------- -------------------- -------------------- --------------------
empqual MASTERS UNIVERSITY UNIVERSITY MASTERS UNIVERSITY
emprank 1 1 1 4 5
empexp 9 9 9 10 11
如果您关于“行数据是动态的”的评论意味着您有一个未知的名称列表,那么您需要编写一个查询,首先获取名称列表,然后使用PIVOT
部分中的名称列表构建上述查询
对“dynamic pivot”的简单搜索应该可以找到大量这样做的示例。此查询适用于您的示例数据:
declare @t table(
empname varchar(20) not null,
empqual varchar(20) not null,
emprank int not null,
empexp int not null
)
insert into @t(empname,empqual,emprank,empexp) values
('Lily','MASTERS',1,9),
('Sasha','UNIVERSITY',1,9),
('Harry','UNIVERSITY',1,9),
('Angela','MASTERS',4,10),
('Joyce','UNIVERSITY',5,11)
select *
from (select empname,empqual,CONVERT(varchar(20),emprank) as emprank,CONVERT(varchar(20),empexp) as empexp from @t) t
unpivot (value FOR measure in (empqual,emprank,empexp)) as unpvt
pivot (MAX(value) for empname in (Lily,Sasha,Harry,Angela,Joyce)) pvt
order by
CASE measure WHEN 'empqual' THEN 0
WHEN 'emprank' THEN 1
WHEN 'empexp' THEN 2
END
结果:
measure Lily Sasha Harry Angela Joyce
------------ -------------------- -------------------- -------------------- -------------------- --------------------
empqual MASTERS UNIVERSITY UNIVERSITY MASTERS UNIVERSITY
emprank 1 1 1 4 5
empexp 9 9 9 10 11
如果您关于“行数据是动态的”的评论意味着您有一个未知的名称列表,那么您需要编写一个查询,首先获取名称列表,然后使用PIVOT
部分中的名称列表构建上述查询
简单搜索“dynamic pivot”应该可以找到很多这样做的例子。使用
pivot
并选择任意聚合(MIN
或MAX
通常是首选)。您可能知道,对于每个组合,您的表将只包含一行,但是SQL Server无法构建一个假设为该组合的计划。@Damien_不相信者,您可以为我提供完整的SQL结构吗?我无法使用PIVOT
,因为行数据是动态的。请使用PIVOT
并选择任意聚合(MIN
或MAX
通常是首选)。您可能知道,对于每个组合,您的表将只包含一行,但是SQL Server无法构建一个假设为该组合的计划。@Damien_不相信者,您可以为我提供完整的SQL结构吗?我无法使用PIVOT
,因为行数据是动态的。这非常好,尽管我没有明确说明'empname'本身不应该是新表的列标题。相反,如果它们是“Column1”、“Column2”等,对应于每个员工,“empname”应该是这些列标题下的值,就像属性一样。我试图编辑您的代码,但是PIVOT
似乎正在根据存储在@cols
中的值获取数据,这些值是“empname”。将@cols
更改为“Column1”、“Column2”等会使所有行都为空。我现在在原始帖子中编辑了修改过的表,使其符合我的要求。请看一下:我只是修改了您的代码,使初始表也具有列名,并且@cols
变量被修改为包含列名而不是'empname'。但是,我的传入数据不太可能包含列名。因此,您是否可以修改代码,以便在插入数据后将列名附加到表中?好的,我更改了代码,这样您就不必添加新列。非常好。谢谢。这太好了,不过我没有明确说明“empname”本身不应该成为新表的列标题。相反,如果它们是“Column1”、“Column2”等,对应于每个员工,“empname”应该是这些列标题下的值,就像属性一样。我试图编辑您的代码,但是PIVOT
似乎正在根据存储在@cols
中的值获取数据,这些值是“empname”。将@cols
更改为“Column1”、“Column2”等会使所有行都为空。我现在在原始帖子中编辑了修改过的表,使其符合我的要求。请看一下:我只是修改了您的代码,使初始表也具有列名,并且@cols
变量被修改为包含列名而不是'empname'。但是,我的传入数据不太可能包含列名。因此,您是否可以修改代码,以便在插入数据后将列名附加到表中?好的,我更改了代码,这样您就不必添加新列。非常好。非常感谢。