将多个记录转换为单个记录T-SQL

时间:2012-11-27 19:49:35

标签: sql-server tsql parsing pivot

数据库问题(我们正在使用T-SQL)

我目前正在研究员工与项目之间的关系。

我们正在尝试重组数据库,以便像这样工作。

旧数据库包含此类信息

Employee ID  Project ID
1            1
1            2
1            3
2            1
2            2

我们需要将其转换为每个员工的单个记录,如此

Project ID  Employee ID 1 Employee ID 2
1           1              2
2           1              2
3           1              null

这是我尝试的sql代码,但我遇到了问题,现在每个员工有三个以上这只是一个例子。相信我,如果只有三个或两个,我会使用最大值或最小值并完成它。

Select [Project ID], min([Employee ID])
From dbo.[Employee Project ID]
where [Employee ID] > select ( Min([Employee ID]) form dbo.[Employee Project ID])
Group by [Project ID]

第一个问题这只给了我第二大,和 如果没有更大的元素,即如果员工一直只有一个项目,那么仍然会返回1为员工ID 1和1为员工ID 2.我已经尝试了案例陈述,他们刚刚炸毁了我。有更简单的方法吗?

我不能简单地回复所有员工,我必须让每个员工都进入自己的领域。如果前端将单个字段的多个员工返回到项目中,则前端无法读取它。我不是在写一个我们带来新公司的前端,他们不能改变他们的代码。

我需要的是每个员工在他自己的领域,我很抱歉最初的混合,我们在这个数据库中有数百名员工,而不是每个项目都有。所以我们需要第一个插槽中最低的员工ID,第二个插槽中的第二个最低值为14.它进入一个看起来像这样的有趣表。我无法控制它的形成方式我只需要将初始数据输入此表单。

Project ID     Attribute       Information
1              Employee ID 1   1
1              Employee ID 2   2
2              Employee ID 1   1
2              Employee ID 2   2
3              Employee ID 1   1
3              Employee ID 2   null

基本上我打算将员工ID 1插入表中,并将员工ID 1插入属性的字段中。老实说,如果你知道一种方法来到底层会更好。我只想拯救你们时间。

2 个答案:

答案 0 :(得分:1)

我完全同意@ JoelCoehoorn的评论,将你的表留在当前的结构中。如果您需要在应用程序和/或用户的其他版本中显示它,那么您可以使用与此类似的PIVOT

select EmployeeId,
  [1] ProjectId1, 
  [2] ProjectId2, 
  [3] ProjectId3
from
(
  select EmployeeID, projectid,
    row_number() over(partition by employeeid order by projectid) rn
  from yourtable
) src
pivot
(
  max(projectid)
  for rn in ([1], [2], [3])
) piv

请参阅SQL Fiddle with Demo

此查询的结果是:

| EMPLOYEEID | PROJECTID1 | PROJECTID2 | PROJECTID3 |
-----------------------------------------------------
|          1 |          1 |          2 |          3 |
|          2 |          1 |          2 |     (null) |

这样做,会使您的桌子处于标准化状态。如果您有100个项目,则不希望在表中添加100个不同的列。您可以使用SQL(如上所述)或应用程序代码轻松操作数据,使其成为您所需的格式。

编辑,根据您的更改,您仍然可以在现有表格结构上使用PIVOT

select projectid,
  [1] EmployeeID1, 
  [2] EmployeeID2
from
(
  select EmployeeID, projectid,
    dense_rank() over(partition by projectid order by employeeid) dr
  from yourtable
) src
pivot
(
  sum(dr)
  for EmployeeId in ([1], [2])
) piv

请参阅SQL Fiddle with Demo

结果:

| PROJECTID | EMPLOYEEID1 | EMPLOYEEID2 |
-----------------------------------------
|         1 |           1 |           2 |
|         2 |           1 |           2 |
|         3 |           1 |      (null) |

答案 1 :(得分:0)

你可以这样做:

declare @t table (EmployeeID int, ProjectId int)
insert @t
select 1, 1
union select 1, 2
union select 1, 3
union select 2, 1
union select 2, 2

select distinct EmployeeID
, 
(
    select ProjectId
    from @t b
    where a.EmployeeId = b.EmployeeId
    for xml path(''), root('Projects')
) ProjectsXML
from @t a

输出

EmployeeID  ProjectsXML
1           <Projects><ProjectId>1</ProjectId><ProjectId>2</ProjectId><ProjectId>3</ProjectId></Projects>
2           <Projects><ProjectId>1</ProjectId><ProjectId>2</ProjectId></Projects>

然而,最好让你的UI代码处理这个问题而不是在SQL级别复杂化。