在 SQL Server 表中加入和分组后转置行
Posted
技术标签:
【中文标题】在 SQL Server 表中加入和分组后转置行【英文标题】:Transpose rows after Join and Groupby in SQL Server table 【发布时间】:2020-09-12 05:32:54 【问题描述】:我有一些 SQL Server 表:
员工 [EmpID (pk)、姓名、职务] 项目 [PID (pk)、EmpID (fk)、PCode、PName、Dept]这些表是多对一的关系,也就是说,一个员工可以处理多个项目。
我想以这样一种方式显示结果,即每个员工只有一行,并且他从事的所有项目都显示在根据 PCode 分组的列部分中。
当生成的列数未知时,我无法理解如何将行转置到列中。
样本数据:
员工:
EmpId Name Designation
------------------------
001 Mat Manager
002 Ash Developer
003 Paul Analyst
项目:
PID EmpID PCode PName Dept
-------------------------------------
1 001 111 Project1 Sales
2 001 111 Project1.1 Retail
3 001 222 Project2 Banking
4 002 222 Project2.1 Retail
样本输出:
EmpID Name Project-1 Project-2 Project-3
---------------------------------------------------------------------------
001 Abc 111,Project1,Sales 111,Project1.1,Retail 222,Project2,Banking
002 Def 222,Project2.1,Retail
【问题讨论】:
以表格格式提供样本数据和您想要的输出 更新了问题。请检查 你使用的是哪个版本的sql server 请向我们展示您的尝试。 【参考方案1】:您可以使用row_number()
在子查询中枚举每个员工的项目,然后使用条件聚合在外部查询中进行透视:
select e.empid, e.name,
max(case when rn = 1 then concat_ws(',', p.pcode, p.pname, p.pdept) end) project1,
max(case when rn = 2 then concat_ws(',', p.pcode, p.pname, p.pdept) end) project2,
max(case when rn = 3 then concat_ws(',', p.pcode, p.pname, p.pdept) end) project3
from employee e
inner join (
select p.*, row_number() over(partition by empid order by pid) rn
from projects p
) p on p.empid = e.empid
group by e.empid, e.name
【讨论】:
它给了我这个错误“错误代码:1064 您的 SQL 语法有错误;请查看与您的 mysql 服务器版本相对应的手册,以在 '(按 empid 顺序分区)附近使用正确的语法通过 pid) rn @user8306074:这是一条 MySQL 错误消息。你为什么要标记你的问题 SQL Server?row_number()
我只在 MySQL 8.0 中可用。
我有一个庞大的数据集,不知道每个员工的最大项目数。那么,在那种情况下,我如何生成多个项目列?【参考方案2】:
您可以使用PIVOT
命令转置您的数据。对于您未知的情况,生成的列数是未知的。您需要查询生成列的列名,然后您可以使用PIVOT
命令将所有列名连接起来,如下查询语句。
DECLARE @columnName NVARCHAR(MAX), @pivotSql NVARCHAR(MAX)
SELECT
em.EmpID,
em.Name,
pr.Pname,
pr.Pcode + ',' + pr.PName + ',' + pr.Dept Detail
INTO #temp
FROM Employee em
INNER JOIN Projects pr ON em.EmpID = pr.EmpID
SELECT
t.PName name
INTO #AllProject
FROM #temp t
GROUP BY t.PName
SET @columnName = '';
DECLARE
@projectName VARCHAR(MAX);
DECLARE cursor_allProject CURSOR
FOR SELECT
name
FROM
#AllProject;
OPEN cursor_allProject;
FETCH NEXT FROM cursor_allProject INTO @projectName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @columnName = @columnName + ', [' + @projectName + ']';
FETCH NEXT FROM cursor_allProject INTO @projectName;
END;
CLOSE cursor_allProject;
DEALLOCATE cursor_allProject;
SET @pivotSql = 'SELECT t.EmpID, t.Name FROM #temp t PIVOT t.Detail (FOR t.Pname IN ('+ @columnName +') )'
EXEC (@pivotSql)
【讨论】:
您使用的是哪个版本的 SQL? 您可以与任何 SQL Server 一起使用以上是关于在 SQL Server 表中加入和分组后转置行的主要内容,如果未能解决你的问题,请参考以下文章