Sql 查询动态 Table 的转置
Sql query for Transpose of a dynamic Table
sqltable如下,
Name Salary NoticePeriod CTC
Jack 1520 15 123
Bruce 1423 35 165
它包含大约 1000 行。
我需要对这个 table 进行转置,这样预期的输出就是
Fields Jack Bruce Mike ..... Sam
Salary 1520 1423 235 .. 561
NoticePeriod 15 35 23 253
CTC 123 165 45 ... 125
我尝试在 Sql Server 2008 中使用 Pivot 和 Unpivot 函数。但是由于 Name 记录很大,Pivot 查询没有帮助。
我的 sql 尝试如下,
SELECT *
FROM (
SELECT NAME,
Salary,
NoticePeriod,
CTC
FROM CTCTABLE WITH (NOLOCK)
) AS queryTable
UNPIVOT(Value FOR NAME IN (NAME, Salary, NoticePeriod, CTC)) AS unpv
PIvot(max(Value) FOR NAME IN (Salary, NoticePeriod, CTC)) pv
在您的情况下,您应该将列 Salary, NoticePeriod, CTC
反透视为行,然后 PIVOT
:
WITH Unpivoted
AS
(
SELECT Name, Fields, SalaryValue
FROM salaries AS s
UNPIVOT
(
SalaryValue
FOR Fields IN(Salary, NoticePeriod, CTC)
) AS u
)
SELECT Fields, jack,bruce
FROM Unpivoted AS u
PIVOT
(
MAX(SalaryValue)
FOR Name IN(Jack, Bruce)
) AS p;
UNPIVOT
会将列 Salary, NoticePeriod, CTC
转换为值:
然后数据透视表将对每个字段值的薪水值进行数据透视表并将名称转换为列。
当然,您必须动态地执行此操作,而不是像这样编写名称列表:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @colnames AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
SELECT @cols = STUFF((SELECT distinct ',' +
QUOTENAME(name)
FROM salaries
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SELECT @query = 'WITH Unpivoted
AS
(
SELECT Name, Fields, SalaryValue
FROM salaries AS s
UNPIVOT
(
SalaryValue
FOR Fields IN(Salary, NoticePeriod, CTC)
) AS u
)
SELECT Fields, ' + @cols + '
FROM Unpivoted AS u
PIVOT
(
MAX(SalaryValue)
FOR Name IN(' + @cols + ')' +
') p';
execute(@query);
这会给你:
- Live Demo(感谢@lad2025)
sqltable如下,
Name Salary NoticePeriod CTC
Jack 1520 15 123
Bruce 1423 35 165
它包含大约 1000 行。
我需要对这个 table 进行转置,这样预期的输出就是
Fields Jack Bruce Mike ..... Sam
Salary 1520 1423 235 .. 561
NoticePeriod 15 35 23 253
CTC 123 165 45 ... 125
我尝试在 Sql Server 2008 中使用 Pivot 和 Unpivot 函数。但是由于 Name 记录很大,Pivot 查询没有帮助。
我的 sql 尝试如下,
SELECT *
FROM (
SELECT NAME,
Salary,
NoticePeriod,
CTC
FROM CTCTABLE WITH (NOLOCK)
) AS queryTable
UNPIVOT(Value FOR NAME IN (NAME, Salary, NoticePeriod, CTC)) AS unpv
PIvot(max(Value) FOR NAME IN (Salary, NoticePeriod, CTC)) pv
在您的情况下,您应该将列 Salary, NoticePeriod, CTC
反透视为行,然后 PIVOT
:
WITH Unpivoted
AS
(
SELECT Name, Fields, SalaryValue
FROM salaries AS s
UNPIVOT
(
SalaryValue
FOR Fields IN(Salary, NoticePeriod, CTC)
) AS u
)
SELECT Fields, jack,bruce
FROM Unpivoted AS u
PIVOT
(
MAX(SalaryValue)
FOR Name IN(Jack, Bruce)
) AS p;
UNPIVOT
会将列 Salary, NoticePeriod, CTC
转换为值:
然后数据透视表将对每个字段值的薪水值进行数据透视表并将名称转换为列。
当然,您必须动态地执行此操作,而不是像这样编写名称列表:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @colnames AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
SELECT @cols = STUFF((SELECT distinct ',' +
QUOTENAME(name)
FROM salaries
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SELECT @query = 'WITH Unpivoted
AS
(
SELECT Name, Fields, SalaryValue
FROM salaries AS s
UNPIVOT
(
SalaryValue
FOR Fields IN(Salary, NoticePeriod, CTC)
) AS u
)
SELECT Fields, ' + @cols + '
FROM Unpivoted AS u
PIVOT
(
MAX(SalaryValue)
FOR Name IN(' + @cols + ')' +
') p';
execute(@query);
这会给你:
- Live Demo(感谢@lad2025)