将多个记录转换为单个记录T-SQL
数据库问题(我们正在使用T-SQL)将多个记录转换为单个记录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]
第一个问题这只是给了我第二大,并 如果是IE没有大的元素,如果只有一个项目的员工一直在它仍然会返回1雇员ID 1和1员工ID 2.我已经试过病例陈述,他们刚刚炸毁了我。有没有更简单的方法来做到这一点?
我不能简单地将所有员工退回来,我必须让每个员工都进入自己的领域。如果它将单个字段的多个员工返回到项目中,则前端无法读取它。我不是在写一个新公司的前端,他们也不能改变他们的代码。
我需要的是每个员工都在自己的领域,对于最初的混淆,我很抱歉,我们有数百名员工在这个数据库中,而不是每个项目上都有。所以我们需要第一个槽中最低的员工编号和第二个槽中第二个最低的员工编号。它会变成一张有趣的表格,看起来像这样。我无法控制这种情况,我只需要将我们的初始数据转化为这种形式即可。
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到用于该属性的字段。老实说,如果你知道一种方法来达到更好的底部表。我只是想节省你们的时间。
我完全同意@ 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
结果从该查询是:
| 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
结果:
| PROJECTID | EMPLOYEEID1 | EMPLOYEEID2 |
-----------------------------------------
| 1 | 1 | 2 |
| 2 | 1 | 2 |
| 3 | 1 | (null) |
@ osfp2328看到我的编辑,“PIVOT”版本仍然可以与员工一起工作 – Taryn
你可以这样做:
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级别复杂化。
不要。不要。这是存储数据的不好方法。旧的方法是存储这些信息的**正确**方式。 –
我们正在将a迁移到新的前端,这不是数据存储的方式。基本上会有一个新的记录,每个都会以不同的方式存储,但有点难以解释,但我不知道如何为属性名称分配这些标签。 – osfp2328
“前端”表示显示和UI逻辑。 “后端”意味着存储和业务规则逻辑。如果你正在转向新的前端,那不应该改变你的存储。您的新前端可能会以新方式**显示**数据,但这与存储方式不同,并且在您之间的某个位置需要可以转发数据的代码。存储方非常需要保留在旧模式中。新的模式只是简单_wrong_。 SQL数据库表**必须**有一个固定数量的columns_,并且编号列几乎总是一个非常严重的设计缺陷。 –