Создать даты и часы из диапазона с фильтром - PullRequest
0 голосов
/ 04 апреля 2019

Исходная таблица выглядит следующим образом:

ID   Date_Start   Date_End     DayOfWeek   Time_Start  Time_End   field1
1    01/02/2018   15/02/2018   4           08:00:00    10:00:00   text1
2    01/06/2018   15/06/2018   2           10:00:00    13:00:00   text1

День 4 представляет четверг, поэтому я хочу сгенерировать только даты и часы DayOfWeek ((4) четверг и (2) вторник в исходной таблице).

Я хотел бы получить этот вывод:

Date        hour     field1
01/02/2018  08       text1
01/02/2018  09       text1
01/02/2018  10       text1
08/02/2018  08       text1
08/02/2018  09       text1
08/02/2018  10       text1
15/02/2018  08       text1
15/02/2018  09       text1
15/02/2018  10       text1
05/06/2018  10       text1
05/06/2018  11       text1
05/06/2018  12       text1
05/06/2018  13       text1
12/06/2018  10       text1
12/06/2018  11       text1
12/06/2018  12       text1
12/06/2018  13       text1

Я пытался отредактировать этот хороший ответ , используя * 24, чтобы получить часы, но никоим образом!

Спасибо.

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Еще один вариант:

SQL> with test (id, date_start, date_end, dayofweek, time_start, time_end, field1) as
  2    (select 1, '01/02/2018', '15/02/2018', 4, '08:00:00', '10:00:00', 'text1' from dual union all
  3     select 2, '01/06/2018', '15/06/2018', 2, '10:00:00', '13:00:00', 'text2' from dual
  4    ),
  5  inter as
  6    (select id, dayofweek, field1, time_start, time_end,
  7            to_date(date_start || time_start, 'dd/mm/yyyyhh24:mi:ss') pstart,
  8            to_date(date_start || time_end,   'dd/mm/yyyyhh24:mi:ss') pend,
  9            to_date(date_end,                 'dd/mm/yyyy') kend
 10     from test
 11    ),
 12  inter2 as
 13    (select i.id,
 14         i.pstart + (t1.column_value - 1)/24 dt,
 15         i.dayofweek,
 16         i.field1,
 17         i.time_start,
 18         i.time_end
 19     From inter i,
 20       table(cast(multiset(select level from dual
 21                           connect by level <= ((kend - pstart) + 1) * 24
 22                          ) as sys.odcinumberlist)) t1
 23    )
 24  select to_char(dt, 'dd/mm/yyyy') cdate,
 25         to_char(dt, 'hh24') chour,
 26         field1
 27  from inter2
 28  where to_char(dt, 'd') = dayofweek
 29    and to_char(dt, 'hh24') between substr(time_start, 1, 2) and substr(time_end, 1, 2);

CDATE      CH FIELD
---------- -- -----
01/02/2018 08 text1
01/02/2018 09 text1
01/02/2018 10 text1
08/02/2018 08 text1
08/02/2018 09 text1
08/02/2018 10 text1
15/02/2018 08 text1
15/02/2018 09 text1
15/02/2018 10 text1
05/06/2018 10 text2
05/06/2018 11 text2
05/06/2018 12 text2
05/06/2018 13 text2
12/06/2018 10 text2
12/06/2018 11 text2
12/06/2018 12 text2
12/06/2018 13 text2

17 rows selected.

SQL>
1 голос
/ 04 апреля 2019

Вот пример того, как вы можете сделать то, что показывает ответ по связанной статье.Обратите внимание, что у Oracle нет типа time, только datetimes, поэтому я не уверен, как вы храните свои часы.Я просто добавил их к датам начала / окончания для целей этого ответа.

WITH test_data AS (
    SELECT 1 AS ID, 
           to_date('01/02/2018','dd/mm/yyyy') AS date_start,
           to_date('15/02/2018','dd/mm/yyyy') AS date_end,
           4 AS dayOfWeek,
           to_date('08:00:00','hh24:mi:ss') AS time_start,
           to_date('10:00:00','hh24:mi:ss') AS time_end,
           'text1' AS field1
    FROM dual

    UNION

    SELECT 2 AS ID, 
           to_date('01/06/2018','dd/mm/yyyy') AS date_start,
           to_date('15/06/2018','dd/mm/yyyy') AS date_end,
           2 AS dayOfWeek,
           to_date('10:00:00','hh24:mi:ss') AS time_start,
           to_date('13:00:00','hh24:mi:ss') AS time_end,
           'text1' AS field1
    FROM dual
), all_hours_in_range AS (
    SELECT d.id, 
           LEVEL, 
           d.date_start, 
           d.date_end, 
           d.date_start + (LEVEL - 1) / 24 AS new_date, 
           d.dayOfWeek, 
           d.time_start,
           d.time_end,
           d.field1
    FROM test_data d
    CONNECT BY LEVEL <= (date_end - date_start) * 24 + 1
      AND PRIOR ID = ID
      AND PRIOR sys_guid() IS NOT NULL
)

SELECT to_char(a.new_date, 'dd/mm/yyyy') AS new_date, 
       to_char(a.new_date, 'hh24') AS new_hour, 
       a.field1
FROM all_hours_in_range a
WHERE to_char(a.new_date, 'hh24') >= to_char(a.time_start, 'hh24') /* Filter to results that are within specified hours */
  AND to_char(a.new_date, 'hh24') <= to_char(a.time_end, 'hh24') 
  AND 1 + TRUNC (a.new_date) - TRUNC (a.new_date, 'IW') = a.dayOfWeek /* Filter to results that are on specified day of week */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...