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