简体   繁体   English

我如何将工作时间转换为布尔值?

[英]how do i convert the working hours to Boolean?

how do I convert the working hours 08:00:00-11:59:00;13:00:00-16:59:00;我如何转换工作时间 08:00:00-11:59:00;13:00:00-16:59:00; into 48 digit Boolean format like成 48 位布尔格式,如

 "000000000000000011111111001111111100000000000000" 

where each digit refers to 30 min granularity using Oracle SQL Query?其中每个数字是指使用 Oracle SQL 查询的 30 分钟粒度?

Assuming you are starting from a string which always has semicolon-separated pairs of from/to times, with a trailing semicolon after the last pair;假设您从一个字符串开始,该字符串始终具有以分号分隔的 from/to 时间对,最后一对后面有一个尾随分号; and those times are always HH24:MI:SS with the seconds always zero as shown;这些时间总是 HH24:MI:SS,如图所示,秒总是零; then... you can split the string into multiple string pairs representing each from/to pair:然后...您可以将字符串拆分为多个字符串对,代表每个从/到对:

select regexp_substr('08:00:00-11:59:00;13:00:00-16:59:00;', '(.*?)(;|-|$)', 1, (2 * level - 1), null, 1),
  regexp_substr('08:00:00-11:59:00;13:00:00-16:59:00;', '(.*?)(;|-|$)', 1, 2 * level, null, 1)
from dual
connect by level <= regexp_count('08:00:00-11:59:00;13:00:00-16:59:00;', ';')
REGEXP_S REGEXP_S
-------- --------
08:00:00 11:59:00
13:00:00 16:59:00

And you can generate all the half-hour blocks in a nominal day (picking one not subject to a DST switch):您可以在一个正常的一天内生成所有半小时的块(选择一个不受 DST 切换影响的块):

select to_char(date '2000-01-01' + ((level - 1) / 48), 'HH24:MI":00"')
from dual
connect by level <= 48
TO_CHAR(
--------
00:00:00
00:30:00
01:00:00
01:30:00
02:00:00
...
23:00:00
23:30:00

And then join those together to see where there is an overlap, using string comparison (which is why the time format matters);然后使用字符串比较将它们连接在一起以查看重叠的地方(这就是时间格式很重要的原因); using CTEs to provide the initial string for simplicity and then the results of the two previous queries:为简单起见,使用 CTE 提供初始字符串,然后提供前两个查询的结果:

with t1 (working_hours) as (
  select '08:00:00-11:59:00;13:00:00-16:59:00;' from dual
),
t2 (working_from, working_to) as (
  select regexp_substr(working_hours, '(.*?)(;|-|$)', 1, (2 * level - 1), null, 1),
    regexp_substr(working_hours, '(.*?)(;|-|$)', 1, 2 * level, null, 1)
  from t1
  connect by level <= regexp_count(working_hours, ';')
),
t3 (block_from) as (
  select to_char(date '2000-01-01' + ((level - 1) / 48), 'HH24:MI":00"')
  from dual
  connect by level <= 48
)
select block_from,
  case when t2.working_from is null then 0 else 1 end as flag
from t3
left join t2 on t2.working_from <= t3.block_from and t2.working_to >= t3.block_from
BLOCK_FROM  FLAG
----------  ----
00:00:00    0
00:30:00    0
...
07:30:00    0
08:00:00    1
08:30:00    1
...
11:00:00    1
11:30:00    1
12:00:00    0
12:30:00    0
13:00:00    1
13:30:00    1
...
16:00:00    1
16:30:00    1
17:00:00    0
...
23:00:00    0
23:30:00    0

And then finally aggregate those together into a single result string:然后最后将它们聚合成一个结果字符串:

with t1 (working_hours) as (
  select '08:00:00-11:59:00;13:00:00-16:59:00;' from dual
),
t2 (working_from, working_to) as (
  select regexp_substr(working_hours, '(.*?)(;|-|$)', 1, (2 * level - 1), null, 1),
    regexp_substr(working_hours, '(.*?)(;|-|$)', 1, 2 * level, null, 1)
  from t1
  connect by level <= regexp_count(working_hours, ';')
),
t3 (block_from) as (
  select to_char(date '2000-01-01' + ((level - 1) / 48), 'HH24:MI":00"')
  from dual
  connect by level <= 48
)
select listagg(case when t2.working_from is null then 0 else 1 end)
  within group (order by t3.block_from) as result
from t3
left join t2 on t2.working_from <= t3.block_from and t2.working_to >= t3.block_from
RESULT
------------------------------------------------
000000000000000011111111001111111100000000000000

db<>fiddle 数据库<>小提琴

If your initial string is actually coming from a table and you need this conversion for multiple rows at once then the connect-by split is a bit more complicated, and a recursive CTE might be more suitable for that part.如果您的初始字符串实际上来自一个表,并且您需要一次对多行进行此转换,则连接拆分会稍微复杂一些,并且递归 CTE 可能更适合该部分。

Just for fun, here's an example .只是为了好玩, 这里有一个例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM