Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / переформатировать данные / 17 сообщений из 17, страница 1 из 1
25.04.2018, 22:07
    #39636404
Olga2018
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
Доброго времени суток.
Стоит задача использовать данные заказчика и сделать update существующих записей. Речь идет о графике рабочей недели
Исходные данные хранятся как character они могут быть:
0700 - 1630
6 - 2:30
6:30 am- 4:00 pm
7:30 - 5
8:30 A - 5:00 P
9:30-6
Нужно их перевести в timestamp формат. Число, месяц, год - не важны, нужно только правильные часы указать
И разбить их на две колонки
Код: plsql
1.
2.
3.
4.
5.
6.
start_time                                             end_time
4/1/2018 7:00:00.000000 AM                4/1/2018 4:30:00.000000 PM
4/1/2018 6:00:00.000000 AM                4/1/2018 2:30:00.000000 PM
4/1/2018 6:30:00.000000 AM                4/1/2018 4:00:00.000000 PM
4/1/2018 7:30:00.000000 AM                4/1/2018 5:00:00.000000 PM
4/1/2018 8:30:00.000000 AM                4/1/2018 5:00:00.000000 PM



и т.д.
Пдскажите пожалуйста, можно ли так сделать?
Начинала с использования
select
case
when
regexp_like(monday_work_hours,'^[6789]?')
then не смогла конвертировать в to_date
...
Рейтинг: 0 / 0
25.04.2018, 23:43
    #39636435
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
Olga2018,

Что-то типа:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
with data as (
              select '0700 - 1630' str from dual union all
              select '6 - 2:30' from dual union all
              select '6:30 am- 4:00 pm' from dual union all
              select '7:30 - 5' from dual union all
              select '8:30 A - 5:00 P' from dual union all
              select '9:30-6' from dual union all
              select '700-800' from dual
             ),
    split as (
              select  regexp_replace(substr(str,1,instr(str,'-') - 1),'(a|p)([^m]|$)','\1m',1,1,'i') from_str,
                      regexp_replace(substr(str,instr(str,'-') + 1),'(a|p)([^m]|$)','\1m',1,1,'i') to_str
                from  data
             ),
      fmt as (
              select  regexp_replace(from_str,'(^\d{3})(\D|$)','0\1\2') from_str,
                      regexp_replace(to_str,'(^\d{3})(\D|$)','0\1\2') to_str,
                      case
                        when regexp_like(from_str,'a|p','i') then 'hh:mi am'
                        else 'hh24:mi'
                      end from_fmt,
                      case
                        when regexp_like(to_str,'a|p','i') then 'hh:mi am'
                        else 'hh24:mi'
                      end to_fmt
                from  split
             )
select  to_timestamp(from_str,from_fmt) from_dt,
        case
          when to_timestamp(from_str,from_fmt) > to_timestamp(to_str,to_fmt)
            then to_timestamp(to_str,to_fmt) + interval '12' hour
          else to_timestamp(to_str,to_fmt)
        end to_dt
  from  fmt
/

FROM_DT                          TO_DT
-------------------------------- --------------------------------
04/01/2018 07:00:00.000000000 AM 04/01/2018 04:30:00.000000000 PM
04/01/2018 06:00:00.000000000 AM 04/01/2018 02:30:00.000000000 PM
04/01/2018 06:30:00.000000000 AM 04/01/2018 04:00:00.000000000 PM
04/01/2018 07:30:00.000000000 AM 04/01/2018 05:00:00.000000000 PM
04/01/2018 08:30:00.000000000 AM 04/01/2018 05:00:00.000000000 PM
04/01/2018 09:30:00.000000000 AM 04/01/2018 06:00:00.000000000 PM
04/01/2018 07:00:00.000000000 AM 04/01/2018 08:00:00.000000000 AM

7 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
25.04.2018, 23:53
    #39636437
Relic Hunter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
Olga2018,

На языке вероятного противника это называется "Garbage in, garbage out.". В общем случае задача - не решаема.
...
Рейтинг: 0 / 0
26.04.2018, 01:17
    #39636456
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
Olga2018,

сумбурный у вас подход... Должно быть как-то так:
1. Определяетесь с всеми вариантами и их шаблонами трансформации, например для простоты сразу используем регулярки оракла:
Пример исходного Пример трансформации Шаблон поиска Маска часов Маска минут AM?0700 07:00 AM ^\d\d\d\d$ ^(\d\d) (\d\d)$ ^(0\d|10|11)\d\d$6 06:00 AM ^\d$ (\d) - .16 04:00 PM ^\d\d$ (\d\d) - ^(0\d|10|11)$8:30 A 08:30 AM ^\d:\d\d (A|P)$ ^(\d) \d:(\d\d) A$
2. Составляете таблицу трансформаций:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with 
  transform( pattern          , pattern_hh , pattern_mi  , am) as (
     select '^\d\d\d\d$'      , '^\d\d'    , '\d\d$'     , '^(0\d|10|11)\d\d$'  from dual union all
     select '^\d$'            , '(\d)'     , '-'         , '.'              from dual union all
     select '^\d\d$'          , '(\d\d)'   , '-'         , '^(0\d|10|11)$'  from dual union all
     select '^\d:\d\d (A|P)$' , '^(\d)'    , '\d:(\d\d)' , 'A$' from dual 
  )
select * 
from transform
/


3. Отделяете начало и конец и трансформируете их в уже понятные hh, mi, am:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
with 
  transform( pattern          , pattern_hh , pattern_mi  , am) as (
     select '^\d\d\d\d$'      , '^\d\d'    , '\d\d$'     , '^(0\d|10|11)\d\d$'  from dual union all
     select '^\d$'            , '(\d)'     , '-'         , '.'              from dual union all
     select '^\d\d$'          , '(\d\d)'   , '-'         , '^(0\d|10|11)$'  from dual union all
     select '^\d:\d\d (A|P)$' , '^(\d)'    , '\d:(\d\d)' , 'A$' from dual 
  )
 ,data as (
              select '0700 - 1630' str from dual union all
              select '6 - 2:30' from dual union all
              select '6:30 am- 4:00 pm' from dual union all
              select '7:30 - 5' from dual union all
              select '8:30 A - 5:00 P' from dual union all
              select '9:30-6' from dual union all
              select '700-800' from dual
             )
 ,split as (
              select  str,
                      trim(substr(str,1,instr(str,'-') - 1)) from_str,
                      trim(substr(str,instr(str,'-') + 1)) to_str
                from  data
           )
select 
   str,
   from_str,
   to_str,
   regexp_substr(from_str, tr_from.pattern_hh, 1,1,null,1) from_hh,
   regexp_substr(from_str, tr_from.pattern_mi, 1,1,null,1) from_mi,
   case when regexp_like(from_str, tr_from.am) then 'AM' 
        when not regexp_like(from_str, tr_from.am) then 'PM' 
        else null 
   end from_am,
   regexp_substr(to_str, tr_to.pattern_hh, 1,1,null,1) to_hh,
   regexp_substr(to_str, tr_to.pattern_mi, 1,1,null,1) to_mi,
   case when regexp_like(to_str, tr_to.am) then 'AM' 
        when not regexp_like(to_str, tr_to.am) then 'PM' 
        else null 
   end to_am
from split
     left join transform tr_from
          on regexp_like(from_str, tr_from.pattern)
     left join transform tr_to
          on regexp_like(from_str, tr_to.pattern);

...
Рейтинг: 0 / 0
26.04.2018, 03:12
    #39636471
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
xtender,

Тут еще допиливать:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
STR              FROM_STR   TO_STR     FROM_HH    FROM_MI    FR TO_HH      TO_MI      TO
---------------- ---------- ---------- ---------- ---------- -- ---------- ---------- --
0700 - 1630      0700       1630                             AM                       PM
6 - 2:30         6          2:30       6                     AM 2                     AM
6:30 am- 4:00 pm 6:30 am    4:00 pm                                                 
7:30 - 5         7:30       5                                                       
8:30 A - 5:00 P  8:30 A     5:00 P     8          30         AM 5          00         PM
9:30-6           9:30       6                                                       
700-800          700        800                                                     

7 rows selected.

SQL>



SY.
...
Рейтинг: 0 / 0
26.04.2018, 04:24
    #39636475
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
SY,

Так это же по табличке выше ясно, что это только набросок, да ещё и с ошибкой копи пасты и замены во втором left join :)
...
Рейтинг: 0 / 0
26.04.2018, 04:46
    #39636478
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
6-9

4/1/2018 6:00:00.000000 AM 4/1/2018 9:00:00.000000 AM
4/1/2018 6:00:00.000000 PM 4/1/2018 9:00:00.000000 PM
4/1/2018 6:00:00.000000 AM 4/1/2018 9:00:00.000000 PM
...
Рейтинг: 0 / 0
26.04.2018, 08:41
    #39636537
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
982183,

я так понимаю 6-9 ето в милитари формате (hh24)
....
stax
...
Рейтинг: 0 / 0
26.04.2018, 08:50
    #39636545
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
xtender,

для am 10|11

может быть 12
Код: plsql
1.
2.
3.
4.
5.
6.
  1* select to_date('12:01 am','hh:mi pm') d from dual
SQL> /

D
-------------------
01.04.2018 00:01:00



.....
stax
...
Рейтинг: 0 / 0
26.04.2018, 12:06
    #39636670
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
Stax,

при указании 12 без am/pm, очевидно, что это должно быть 12pm
...
Рейтинг: 0 / 0
26.04.2018, 12:14
    #39636679
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
Staxя так понимаю 6-9 ето в милитари формате (hh24)

Но у него:

7:30 - 5
4/1/2018 7:30:00.000000 AM 4/1/2018 5:00:00.000000 PM
...
Рейтинг: 0 / 0
26.04.2018, 14:05
    #39636763
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
982183Но у него:

7:30 - 5
4/1/2018 7:30:00.000000 AM 4/1/2018 5:00:00.000000 PM

А тут исходим из тoго что to_date >= from_date.

SY.з
...
Рейтинг: 0 / 0
26.04.2018, 14:07
    #39636765
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
xtenderStax,

при указании 12 без am/pm, очевидно, что это должно быть 12pm
хз

12 тож ам может бить

1210-1230?



зи
имхо, в случае полсуток надо явно указывать рм/ам

2:30-4 ето скоко?

.....
stax
...
Рейтинг: 0 / 0
26.04.2018, 14:13
    #39636773
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
Stax12 тож ам может бить

1210-1230?отталкиваться надо от того, что адекватный человек не будет указывать двусмысленные значения. И почему тебя именно 12 задело, а не 4 например? 4 тоже может быть 4am/4pm
...
Рейтинг: 0 / 0
26.04.2018, 14:36
    #39636785
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
xtenderStax12 тож ам может бить

1210-1230?отталкиваться надо от того, что адекватный человек не будет указывать двусмысленные значения. И почему тебя именно 12 задело, а не 4 например? 4 тоже может быть 4am/4pm

из-за маски '^(0\d| 10 | 11 )\d\d$'

ps
я б регуляркой не решал, создал ф-циію
1) плохо знаю
2) можно лог вести

....
stax
...
Рейтинг: 0 / 0
26.04.2018, 14:45
    #39636793
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
Staxиз-за маски '^(0\d| 10 | 11 )\d\d$'ок, ну тогда как бы ты тогда расставил AM/PM для:
0000
0100
1200
1300
2300
...
Рейтинг: 0 / 0
26.04.2018, 16:27
    #39636865
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
переформатировать данные
xtenderStaxиз-за маски '^(0\d| 10 | 11 )\d\d$'ок, ну тогда как бы ты тогда расставил AM/PM для:
0000
0100
1200
1300
2300

0000 --24
0100 --?
1200 --?
1300 --24
2300 --24


если AM/PM нет, считаю hh24
иначе однозначно не определить (06:00 - 11:30)

можно конечно усложнять 00,13-23,stop<start и тд, но регуляркой для меня ето сложно

кстати 12:30 > 10:00 и ???


.....
stax
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / переформатировать данные / 17 сообщений из 17, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]