如何从行格式创建日历?

时间:2018-01-11 15:47:26

标签: sql oracle

我有这样一张桌子:

ID  DATE     ROOM    OWNER  FROM_TIME  TO_TIME

1   jan-1-18 Room_A  Jack   09:00      10:00
2   jan-1-18 Room_A  John   10:00      11:00
3   jan-1-18 Room_B  John   09:00      10:00

如何将数据转移到:

Hour        Room_A       Room_B
09:00       Jack         John     
10:00       John
11:00       .... 

我知道我会使用一些" pivot"功能,但我不知道哪个!

由于

2 个答案:

答案 0 :(得分:1)

这是一种方法,使用pivot运算符(不是函数!) - 所以此解决方案需要Oracle 11.1或更高版本。对于早期版本,您可以使用条件聚合。 (实际上,我允许使用LISTAGG()函数为同一个房间和同一时段提供多个"所有者"因此这将需要Oracle版本11.2。您可以将其替换为MAX()如果每个时段最多只有一个所有者,那么这将在11.1中有效。)

with
  test_data ( id, dt, room, owner, from_time, to_time ) as (
    select 1, 'jan-1-18', 'Room_A', 'Jack', '09:00', '10:00' from dual union all
    select 2, 'jan-1-18', 'Room_A', 'John', '10:00', '11:00' from dual union all
    select 3, 'jan-1-18', 'Room_B', 'John', '09:00', '10:00' from dual
  )
select dt, from_time, to_time, room_a, room_b
from   ( select dt, room, owner, from_time, to_time from test_data )
pivot  ( listagg(owner, ',') within group (order by owner)   -- or just max(owner)
                             for room in ('Room_A' as room_a, 'Room_B' as room_b) )
order by dt, from_time
;

DT       FROM_TIME TO_TIME ROOM_A ROOM_B
-------- --------- ------- ------ ------
jan-1-18 09:00     10:00   Jack   John
jan-1-18 10:00     11:00   John     

答案 1 :(得分:1)

假设from_time和to_time之间的传递时间超过一小时,并且在同一小时内为同一个房间预订了更多名称,请尝试使用pivot运算符,并在下面添加with构造方式。

您必须知道room的所有可能值。

ID  DATE     ROOM    OWNER  FROM_TIME  TO_TIME

1   jan-1-18 Room_A  Jack   09:00      10:00
2   jan-1-18 Room_A  John   10:00      11:00
3   jan-1-18 Room_B  John   09:00      10:00
4   jan-1-18 Room_A  Jill   09:00      11:00

我在09:00到11:00之间添加了占据A室的“Jill”案例:查询分别显示了两个小时:

with data as
     (select level-1 l from dual connect by level <= 100),
    dtset as
     (select id_row, day, room, owner,
             to_char(to_date(from_time, 'hh24:mi') + (l/24), 'hh24:mi') from_time,
             to_char(to_date(from_time, 'hh24:mi') + ((l+1)/24), 'hh24:mi') to_time
        from your_table_name, data
       where l < (24 * (to_date(to_time, 'hh24:mi') - to_date(from_time, 'hh24:mi'))))
select *
  from (select day, from_time, to_time, room, owner
          from dtset)   
        pivot (listagg(owner, ', ') within group (order by owner) for room in ('Room_A' as Room_A, 'Room_B' as Room_B))
  order by day, to_time;

简而言之,具体化dtset将两小时时段划分为两个一小时的时段。结果:

DATA        FROM_TIME   TO_TIME   ROOM_A         ROOM_B
----------  ---------   --------  ----------     -------
11/01/2018  09:00       10:00     Jack, Jill     John
11/01/2018  10:00       11:00     Jill, John