Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在Oracle中连接并缩短一周中的天数_Sql_Oracle_Datetime_Oracle11g - Fatal编程技术网

Sql 在Oracle中连接并缩短一周中的天数

Sql 在Oracle中连接并缩短一周中的天数,sql,oracle,datetime,oracle11g,Sql,Oracle,Datetime,Oracle11g,我有计时栏 M 8:00 AM - 5:00 PM | Tu 8:00 AM - 5:00 PM | W 8:00 AM - 5:00 PM | Th 8:00 AM - 5:00 PM | F 8:00 AM - 5:00 PM 希望将其生成为 M-F 8:00 AM - 5:00 PM 有时,时间可能会随着时间的推移而改变 M 9:00 am - 9:00 pm | Tu 9:00 am - 9:00 pm | W 9:00 am - 9:00 pm | Th 9:00 am - 9:0

我有计时栏

M 8:00 AM - 5:00 PM | Tu 8:00 AM - 5:00 PM | W 8:00 AM - 5:00 PM | Th 8:00 AM - 5:00 PM | F 8:00 AM - 5:00 PM
希望将其生成为

M-F 8:00 AM - 5:00 PM
有时,时间可能会随着时间的推移而改变

M 9:00 am - 9:00 pm | Tu 9:00 am - 9:00 pm | W 9:00 am - 9:00 pm | Th 9:00 am - 9:00 pm | F 9:00 am - 9:00 pm | Sa 9:00 am - 9:00 pm | Su 10:00 am - 6:00 pm
在这种情况下,我必须生成

M-Sa 9:00 am - 9:00 pm | Su 10:00 am - 6:00 pm

看一看这个循序渐进的例子。遵循代码中编写的注释

把它当作你可能会做的指南,因为如果在中间某个地方有不同的时间跨度(例如星期四),这种方法就不能正常工作。分组仍然可以,但以缩写形式命名的日期会有点错误,因为您会得到例如M-Su上午9:00-晚上9:00 | Th上午9:00-下午4:00。如果你不介意的话,很好

SQL> with
  2  test (id, col) as
  3    (
  4     select 1, 'M 8:00 AM - 5:00 PM | Tu 8:00 AM - 5:00 PM | W 8:00 AM - 5:00 PM | Th 8:00 AM - 5:00 PM | F 8:00 AM - 5:00 PM' from dual union all
  5     select 2, 'M 9:00 am - 9:00 pm | Tu 9:00 am - 9:00 pm | W 9:00 am - 9:00 pm | Th 9:00 am - 9:00 pm | F 9:00 am - 9:00 pm | Sa 9:00 am - 9:00 pm | Su 10:00 am - 6:00 pm' from dual
  6    ),
  7  temp as
  8    -- split column to rows
  9    (select id,
 10            column_value rn,
 11            trim(regexp_substr(upper(col), '[^|]+', 1, column_value)) val
 12     from test join table(cast(multiset(select level from dual
 13                                        connect by level <= regexp_count(col, '\|') + 1
 14                                       ) as sys.odcinumberlist)) on 1 = 1
 15    ),
 16  extr as
 17    -- extract day and time span into separate columns (for aggregating purposes)
 18    (
 19     select id,
 20            rn,
 21            substr(val, 1, instr(val, ' ')) c_day,
 22            substr(val, instr(val, ' ') + 1) c_period
 23     from temp
 24    ),
 25  agg1 as
 26    (-- group values from the previous step
 27     select id,
 28            listagg(trim(c_day), ', ') within group (order by rn) days,
 29            c_period
 30     from extr
 31     group by id, c_period
 32    )
 33    -- the final result
 34  select id,
 35         listagg
 36           (initcap(regexp_substr(days, '^\w+') ||'-'|| regexp_substr(days, '\w+$')) || ' ' || lower(c_period), ' | ')
 37            within group (order by id)
 38            val
 39  from agg1
 40  group by id
 41  order by id;

 ID VAL
--- --------------------------------------------------
  1 M-F 8:00 am - 5:00 pm
  2 M-Sa 9:00 am - 9:00 pm | Su-Su 10:00 am - 6:00 pm

SQL>
或者,您可以命名共享相同时间跨度的所有天,而不是将其缩短那么多,这样无论哪几天的时间跨度不同,都会返回正确的结果。例如:

 <... snip, as previous lines are not modified ...>
 25  agg1 as
 26    (-- group values from the previous step
 27     select id,
 28            listagg(trim(initcap(c_day)), ', ') within group (order by rn) ||' ' || upper(c_period) val
 29     from extr
 30     group by id, c_period
 31    )
 32    -- the final result
 33  select id,
 34         listagg (val, ' | ') within group (order by id) val
 35  from agg1
 36  group by id
 37  order by id;

 ID VAL
--- ----------------------------------------------------------------------------------------------------
  1 M, Tu, W, Th, F 8:00 AM - 5:00 PM
  2 M, Tu, W, F, Sa 9:00 AM - 9:00 PM | Su 10:00 AM - 6:00 PM | Th 9:00 AM - 4:00 PM

SQL>

谢谢,第二个很有帮助。