【问题标题】:Sql query for Transpose of a dynamic Table用于动态表转置的 Sql 查询
【发布时间】:2015-10-20 10:56:29
【问题描述】:

sql表如下,

    Name    Salary   NoticePeriod   CTC
    Jack     1520       15          123
    Bruce    1423       35          165 

它包含大约 1000 行。

我需要对这个表做一个转置,这样预期的输出是

    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

【问题讨论】:

标签: sql sql-server database sql-server-2008 pivot


【解决方案1】:

在您的情况下,您应该将列 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);

这会给你:

【讨论】:

  • @lad2025 - 感谢演示
  • 感谢大家的努力。但 Jack 是插入基表的第一条记录。完成 Pivot and Unpivot 后,Bruce 列先出现,Jack 出现。我们不能根据表记录插入顺序重新排列列吗?
  • @CheralIrumborai - 在 SQL Server 和大多数 RDBMS 中,不能授予行的顺序,并且它很重要。但在你的情况下,如果你想按插入的值排序,你可以从变量中删除distinctSELECT @cols = STUFF((SELECT ',' + QUOTENAME(name) FROM salaries FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') , 1, 1, ''); 这样jack 将是第一个,但我建议你指定一个 order by 子句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-07
  • 2021-05-24
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多