我正在尝试将数据导出为CSV,并且需要将第二个表中的多个列转换为行。要启动,我在第二个表中没有固定数量的行,但需要在导出中使用固定数量的字段。这是我的数据样本(我希望它能解决我的问题)。数据加入StudentID。使用MS SQL Server 2014。
用户表
StudentID | Last Name | First Name | Middle Name/Initial | Is Active | Grade | School Name
___________________________________________________________________________________________
1 | Pinciati | Donna | J | Y | 10 | High
2 | Hyde | Steven | K | Y | 11 | Middle
3 | Foreman | Eric | L | Y | 10 | High
4 | Kelso | Michael | G | Y | 11 | High
警报表
ID | StudentID | Alert Type | Alert Comments
___________________________________________________
1 | 2 | Asthma | NULL
2 | 2 | Allergy | Bee Sting
3 | 3 | Allergy | Peanut
4 | 4 | Medial Equipment | Crutches
5 | 4 | Allergy | Bee Sting
我的结果集需要如下所示:
StudentID | Last Name | First Name | Middle Name/Initial | Is Active | Grade | School Name | Alert Type 1 | Alert Comments 1 | Alert Type 2 | Alert Comments 2 | Alert Type 3 | Alert Comments 3
1 | Pinciati | Donna | J | Y | 10 | High | NULL | NULL | NULL | NULL | NULL | NULL
2 | Hyde | Steven | K | Y | 11 | Middle | Asthma | NULL | Allergy | Bee Sting | NULL | NULL
3 | Foreman | Eric | L | Y | 10 | High | Allergy | Peanut | NULL | NULL | NULL | NULL
4 | Kelso | Michael | G | Y | 11 | High | Medial Equipment | Crutches | Allergy | Bee Sting | NULL | NULL
我知道我的警报比我的数据更多,但模板中有固定数量的字段我无法更改,因此即使它们为NULL,我也必须填写所有警报字段。
帮助我Obi-Wan Kenobi;你是我唯一的希望!
答案 0 :(得分:1)
使用子查询或 common table expression 与 row_number() ,您可以在StudentId
上保持联接并根据该行进行汇总号码(rn
)。
select
s.StudentID
, s.LastName
, s.FirstName
, s.MiddleName
, s.IsActive
, s.Grade
, s.SchoolName
, AlertType_1 = max(case when rn = 1 then al.AlertType else null end)
, AlertComments_1 = max(case when rn = 1 then al.AlertComments else null end)
, AlertType_2 = max(case when rn = 2 then al.AlertType else null end)
, AlertComments_2 = max(case when rn = 2 then al.AlertComments else null end)
, AlertType_3 = max(case when rn = 3 then al.AlertType else null end)
, AlertComments_3 = max(case when rn = 3 then al.AlertComments else null end)
from dbo.student as s
left join (
select StudentId, AlertType, AlertComments
, rn = row_number() over (
partition by StudentId
order by AlertType, AlertComments
)
from dbo.Alert
) as al on s.StudentId = al.StudentId
group by
s.StudentID
, s.LastName
, s.FirstName
, s.MiddleName
, s.IsActive
, s.Grade
, s.SchoolName
rextester:http://rextester.com/YMDQI47779
测试设置:
create table Student (
StudentID int
, LastName nvarchar(32)
, FirstName nvarchar(32)
, MiddleName nvarchar(32)
, IsActive char(1)
, Grade int
, SchoolName nvarchar(32)
);
insert into dbo.Student values
(1,'Pinciati','Donna','J','Y',10,'High')
,(2,'Hyde','Steven','K','Y',11,'Middle')
,(3,'Foreman','Eric','L','Y',10,'High')
,(4,'Kelso','Michael','G','Y',11,'High');
create table dbo.Alert (
ID int
, StudentID int
, AlertType nvarchar(64)
, AlertComments nvarchar(64)
);
insert into dbo.Alert values
(1,2,'Asthma','NULL')
,(2,2,'Allergy','Bee Sting')
,(3,3,'Allergy','Peanut')
,(4,4,'Medial Equipment','Crutches')
,(5,4,'Allergy','Bee Sting');
查询:
;with al as (
select StudentId, AlertType, AlertComments
, rn = row_number() over (
partition by StudentId
order by AlertType, AlertComments
)
from dbo.Alert
)
select
s.StudentID
, s.LastName
, s.FirstName
, s.MiddleName
, s.IsActive
, s.Grade
, s.SchoolName
, AlertType_1 = max(case when rn = 1 then al.AlertType else null end)
, AlertComments_1 = max(case when rn = 1 then al.AlertComments else null end)
, AlertType_2 = max(case when rn = 2 then al.AlertType else null end)
, AlertComments_2 = max(case when rn = 2 then al.AlertComments else null end)
, AlertType_3 = max(case when rn = 3 then al.AlertType else null end)
, AlertComments_3 = max(case when rn = 3 then al.AlertComments else null end)
from dbo.student as s
left join al on s.StudentId = al.StudentId
group by
s.StudentID
, s.LastName
, s.FirstName
, s.MiddleName
, s.IsActive
, s.Grade
, s.SchoolName
结果:
+-----------+----------+-----------+------------+----------+-------+------------+-------------+-----------------+------------------+-----------------+-------------+-----------------+
| StudentID | LastName | FirstName | MiddleName | IsActive | Grade | SchoolName | AlertType_1 | AlertComments_1 | AlertType_2 | AlertComments_2 | AlertType_3 | AlertComments_3 |
+-----------+----------+-----------+------------+----------+-------+------------+-------------+-----------------+------------------+-----------------+-------------+-----------------+
| 1 | Pinciati | Donna | J | Y | 10 | High | NULL | NULL | NULL | NULL | NULL | NULL |
| 2 | Hyde | Steven | K | Y | 11 | Middle | Allergy | Bee Sting | Asthma | NULL | NULL | NULL |
| 3 | Foreman | Eric | L | Y | 10 | High | Allergy | Peanut | NULL | NULL | NULL | NULL |
| 4 | Kelso | Michael | G | Y | 11 | High | Allergy | Bee Sting | Medial Equipment | Crutches | NULL | NULL |
+-----------+----------+-----------+------------+----------+-------+------------+-------------+-----------------+------------------+-----------------+-------------+-----------------+
答案 1 :(得分:0)
试试这个:
with alert as (
select f0.*,
row_number() over(partition by f0.studientID order by f0.ID) rang from Alert_TAble f0
)
select f0.*,
f1.AlertType as AlertType1, f1.AlertComment as AlertComment1,
f2.AlertType as AlertType2, f2.AlertComment as AlertComment2,
f3.AlertType as AlertType3, f3.AlertComment as AlertComment3
from User_Table f0
left outer join alert f1 on f0.studientID=f1.studientID and f1.rang=1
left outer join alert f2 on f0.studientID=f2.studientID and f2.rang=2
left outer join alert f3 on f0.studientID=f3.studientID and f3.rang=3