在没有聚合的sql server中取消PIVOT
我有一个在没有聚合的sql server中取消PIVOT,sql,sql-server,tsql,sql-server-2012,unpivot,Sql,Sql Server,Tsql,Sql Server 2012,Unpivot,我有一个表格,如下所示 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
表格
,如下所示
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
我需要将此表的列转换为行
预期产出:
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
,但我不确定需要选择哪个列作为透视列。请帮忙……这是最重要的。如果您想要一个特定的输出顺序,我建议使用一个辅助表,将3个字符的日期名称映射到排序索引(如果需要,还有完整的长度名称):
结果:
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
如您所知,如果可能的话,最好重新设计您的数据库,使其与原始结果集更为相似-相同“类型”的数据应该在单个列中,并且数据应该作为数据建模,而不是嵌入到列名中
如果输出顺序和日期名称特别重要,则扩展变量:
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
谢谢damien.但是可以返回DayID而不是dayname吗?就像1代表sun,2代表mon?@bmsqldev-您应该能够修改我的第二个版本,它使用一个辅助表来引入关于日期的额外信息。我认为最好的方法是运行7个查询,每个查询一周中的一天。如果这是一些例行的事情,那么您可以创建一个存储过程或使用动态查询来完成这项工作。
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