sql 服务器中的 UNPIVOT 没有聚合
UNPIVOT in sql server without Aggregate
我有一个 Table
如下。
OfficeID SunFrom SunTo MonFrom MonTo TueFrom TueTo WedFrom WedTo ThuFrom ThuTo FriFrom FriTo SatFrom SatTo
51834 12 17 8 22 8 22 8 22 8 22 9 21 8 19
我需要将此 table 的列转换为行
预期输出:
Officeid Day Daystart DayEnd
51834 Sunday 12 17
51834 Monday 8 22
51834 Tuesday 8 22
51834 Wednesday 8 22
51834 Thursday 8 22
51834 Friday 9 21
51834 Saturday 8 19
我尝试使用 UNPIVOT
,但我不确定我需要选择哪一列作为 pivot column
。请帮忙....
这就是大部分内容。如果您想要特定的输出顺序,我建议使用辅助 table 将 3 个字符的日期名称映射到排序索引(以及全长名称,如果需要的话):
declare @t table (OfficeID int,SunFrom int,SunTo int,MonFrom int,MonTo int,
TueFrom int,TueTo int,WedFrom int,WedTo int,
ThuFrom int,ThuTo int,FriFrom int,FriTo int,
SatFrom int,SatTo int)
insert into @t(OfficeID,SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo,
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo) values
(51834,12,17,8,22,8,22,8,22,8,22,9,21,8,19)
select
OfficeID,Day,
MAX(CASE WHEN Endpoint='From' THEN EndpointTime END) as Daystart,
MAX(CASE WHEN Endpoint='To' THEN EndpointTime END) as DayEnd
from
@t t
unpivot
(EndpointTime for DayAndEndPoint in (SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo,
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo)) a
cross apply
(select SUBSTRING(DayAndEndpoint,1,3) as Day,SUBSTRING(DayAndEndpoint,4,4) as Endpoint) b
group by
OfficeID,Day
结果:
OfficeID Day Daystart DayEnd
----------- ---- ----------- -----------
51834 Fri 9 21
51834 Mon 8 22
51834 Sat 8 19
51834 Sun 12 17
51834 Thu 8 22
51834 Tue 8 22
51834 Wed 8 22
正如您所希望知道的那样,如果可能的话,最好重新设计您的数据库,使其比原始结果集更接近于此结果集 - 相同 "type" 的数据应该在一个列中,并且数据应该被建模为数据而不是嵌入列名中。
如果输出顺序和日期名称特别重要,则扩展变体:
declare @t table (OfficeID int,SunFrom int,SunTo int,MonFrom int,MonTo int,
TueFrom int,TueTo int,WedFrom int,WedTo int,
ThuFrom int,ThuTo int,FriFrom int,FriTo int,
SatFrom int,SatTo int)
insert into @t(OfficeID,SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo,
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo) values
(51834,12,17,8,22,8,22,8,22,8,22,9,21,8,19)
declare @DayNameAndSort table (Day varchar(3) not null,ExtendedName varchar(19) not null,SortOrder int not null)
insert into @DayNameAndSort (Day,ExtendedName,SortOrder) values
('Fri','Friday', 5),
('Mon','Monday', 1),
('Sat','Saturday', 6),
('Sun','Sunday', 0),
('Thu','Thursday', 4),
('Tue','Tuesday', 2),
('Wed','Wednesday',3)
;With ReOriented as (
select
OfficeID,Day,
MAX(CASE WHEN Endpoint='From' THEN EndpointTime END) as Daystart,
MAX(CASE WHEN Endpoint='To' THEN EndpointTime END) as DayEnd
from
@t t
unpivot
(EndpointTime for DayAndEndPoint in (SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo,
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo)) a
cross apply
(select SUBSTRING(DayAndEndpoint,1,3) as Day,SUBSTRING(DayAndEndpoint,4,4) as Endpoint) b
group by
OfficeID,Day
)
select
OfficeID,ExtendedName,Daystart,DayEnd
from
ReOriented r
inner join
@DayNameAndSort s
on
r.Day = s.Day
order by s.SortOrder
我有一个 Table
如下。
OfficeID SunFrom SunTo MonFrom MonTo TueFrom TueTo WedFrom WedTo ThuFrom ThuTo FriFrom FriTo SatFrom SatTo
51834 12 17 8 22 8 22 8 22 8 22 9 21 8 19
我需要将此 table 的列转换为行
预期输出:
Officeid Day Daystart DayEnd
51834 Sunday 12 17
51834 Monday 8 22
51834 Tuesday 8 22
51834 Wednesday 8 22
51834 Thursday 8 22
51834 Friday 9 21
51834 Saturday 8 19
我尝试使用 UNPIVOT
,但我不确定我需要选择哪一列作为 pivot column
。请帮忙....
这就是大部分内容。如果您想要特定的输出顺序,我建议使用辅助 table 将 3 个字符的日期名称映射到排序索引(以及全长名称,如果需要的话):
declare @t table (OfficeID int,SunFrom int,SunTo int,MonFrom int,MonTo int,
TueFrom int,TueTo int,WedFrom int,WedTo int,
ThuFrom int,ThuTo int,FriFrom int,FriTo int,
SatFrom int,SatTo int)
insert into @t(OfficeID,SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo,
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo) values
(51834,12,17,8,22,8,22,8,22,8,22,9,21,8,19)
select
OfficeID,Day,
MAX(CASE WHEN Endpoint='From' THEN EndpointTime END) as Daystart,
MAX(CASE WHEN Endpoint='To' THEN EndpointTime END) as DayEnd
from
@t t
unpivot
(EndpointTime for DayAndEndPoint in (SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo,
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo)) a
cross apply
(select SUBSTRING(DayAndEndpoint,1,3) as Day,SUBSTRING(DayAndEndpoint,4,4) as Endpoint) b
group by
OfficeID,Day
结果:
OfficeID Day Daystart DayEnd
----------- ---- ----------- -----------
51834 Fri 9 21
51834 Mon 8 22
51834 Sat 8 19
51834 Sun 12 17
51834 Thu 8 22
51834 Tue 8 22
51834 Wed 8 22
正如您所希望知道的那样,如果可能的话,最好重新设计您的数据库,使其比原始结果集更接近于此结果集 - 相同 "type" 的数据应该在一个列中,并且数据应该被建模为数据而不是嵌入列名中。
如果输出顺序和日期名称特别重要,则扩展变体:
declare @t table (OfficeID int,SunFrom int,SunTo int,MonFrom int,MonTo int,
TueFrom int,TueTo int,WedFrom int,WedTo int,
ThuFrom int,ThuTo int,FriFrom int,FriTo int,
SatFrom int,SatTo int)
insert into @t(OfficeID,SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo,
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo) values
(51834,12,17,8,22,8,22,8,22,8,22,9,21,8,19)
declare @DayNameAndSort table (Day varchar(3) not null,ExtendedName varchar(19) not null,SortOrder int not null)
insert into @DayNameAndSort (Day,ExtendedName,SortOrder) values
('Fri','Friday', 5),
('Mon','Monday', 1),
('Sat','Saturday', 6),
('Sun','Sunday', 0),
('Thu','Thursday', 4),
('Tue','Tuesday', 2),
('Wed','Wednesday',3)
;With ReOriented as (
select
OfficeID,Day,
MAX(CASE WHEN Endpoint='From' THEN EndpointTime END) as Daystart,
MAX(CASE WHEN Endpoint='To' THEN EndpointTime END) as DayEnd
from
@t t
unpivot
(EndpointTime for DayAndEndPoint in (SunFrom,SunTo,MonFrom,MonTo,TueFrom,TueTo,
WedFrom,WedTo,ThuFrom,ThuTo,FriFrom,FriTo,SatFrom,SatTo)) a
cross apply
(select SUBSTRING(DayAndEndpoint,1,3) as Day,SUBSTRING(DayAndEndpoint,4,4) as Endpoint) b
group by
OfficeID,Day
)
select
OfficeID,ExtendedName,Daystart,DayEnd
from
ReOriented r
inner join
@DayNameAndSort s
on
r.Day = s.Day
order by s.SortOrder