有关约会计划的Oracle SQL帮助
我有一个包含以下信息的约会表:有关约会计划的Oracle SQL帮助,sql,oracle,Sql,Oracle,我有一个包含以下信息的约会表: id agent_id starts_at ends_at ... 给代理人一个从早上9点开始到下午6点18点结束的时间表 并在2011年1月1日上午10:00至11:00之间预约 有没有可能把他的时间表分成30分钟的倍数 并在Oracle中使用SQL获得以下结果: date, slotnum, agent_id, starts_at, ends_at, appointment_id 2011-01-01, 1, 1, 09:00, 09:30, (null)
id
agent_id
starts_at
ends_at
...
给代理人一个从早上9点开始到下午6点18点结束的时间表
并在2011年1月1日上午10:00至11:00之间预约
有没有可能把他的时间表分成30分钟的倍数
并在Oracle中使用SQL获得以下结果:
date, slotnum, agent_id, starts_at, ends_at, appointment_id
2011-01-01, 1, 1, 09:00, 09:30, (null)
2011-01-01, 2, 1, 09:30, 10:00, (null)
2011-01-01, 3, 1, 10:00, 10:30, 1
2011-01-01, 4, 1, 10:30, 11:00, 1
2011-01-01, 5, 1, 11:00, 11:30, (null)
...
...
2011-01-01,, 18, 1, 17:30, 18:00, (null)
提前谢谢。是的,有可能。你留下了很多未指明的细节。我假设您还有一个agents表,以及agent\u id、start\u hour和end\u hour,其中hour字段是0到24之间的整数。这意味着一个给定代理的工作日在不同的日子里没有变化。我还假设驱动查询的用户输入将是一个agent_id和一个应该查看日程安排的日期,后者表示为一个日期 我现在无法测试这一点,但我认为它基本上可以满足您的要求:
with agent_workday as (
select agent_id,
:date + start_hour/24 agent_start_time,
:date + end_hour/24 agent_end_time
from agents
where agent_id = :agent
), agent_slots as (
select agent_id,
level slotnum,
agent_start_time + (level-1)/48 slot_start,
agent_start_time + level/48 slot_end
from agent_workday
connect by level <= (agent_end_time-agent_start_time)*48
)
select :date, slotnum, agent_slots.agent_id,
TO_CHAR(slot_start, 'HH24:MI'), TO_CHAR(slot_end, 'HH24:MI'),
appointment_id
from agent_slots left join appointments
on appointments.agent_id = agent_slots.agent_id
and agent_slots.block_start >= appointments.starts_at
and agent_slots.block_end <= appointments.ends_at
order by slotnum
尝试以下未测试的选项:
WITH time_slots AS
(
SELECT b.starts ,
b.starts + (rownum -1) * 0.5/24 starts_at,
b.starts + (rownum) * 0.5/24 ends_at,
rownum AS slotnum
FROM ALL_OBJECTS a,
(
SELECT TRUNC(sysdate) + 9/24 AS starts --Can have the actual date you are looking for instead of SYSDATE
FROM DUAL
) b
)
SELECT a.starts AS "DATE",
a.slotnum,
b.agent_id,
TO_CHAR(a.starts_at, 'HH24:MI') AS starts_at,
TO_CHAR(a.ends_at, 'HH24:MI') AS ends_at,
b.id AS appointment_id
FROM time_slots a LEFT JOIN appointments b
ON (b.starts_at >= a.starts_at AND b.starts_at <= a.ends_at) OR
(b.ends_at >= a.starts_at AND b.starts_at <= a.ends_at)
在做这件事的过程中,我自己学到了一些东西。希望这能给你一个这样做的方法。我的示例在每个表中都有一条记录,因此如果有更多记录,您可能需要调整它以提高性能
create table t_agent
(id number(9),
agent_id number(9),
starts_at timestamp,
ends_at timestamp);
insert into t_agent values (1,100, timestamp'2011-01-01 09:00:00.0 AMERICA/CHICAGO',timestamp'2011-01-01 18:00:00.0 AMERICA/CHICAGO');
create table t_appointment
(id number(9),
agent_id number(9),
start_time timestamp,
end_time timestamp);
insert into t_appointment values (1,100, timestamp'2011-01-01 10:00:00.0 AMERICA/CHICAGO',timestamp'2011-01-01 11:00:00.0 AMERICA/CHICAGO');
with agent_hours as
(select extract(hour from ends_at) end_time,
extract(hour from starts_at) start_time,
to_char(trunc(starts_at)) appointment_date,
starts_at,
ends_at,
agent_id
from t_agent
where agent_id=100)
select slots.appointment_date,
slots.slotnum,
slots.starttime,
slots.endtime,
case when app.start_time >= slots.full_starttime and app.start_time < slots.full_endtime
or
app.end_time > slots.full_starttime and app.end_time <= slots.full_endtime
then app.id else null end app_id
from t_appointment app,
(select agent_hours.appointment_date,
rownum slotnum,
agent_hours.agent_id,
to_char((trunc(starts_at) + (.5/24) * agent_hours.start_time * 2) + ((rownum -1) * .5/24),' HH24:mi') starttime,
to_char((trunc(starts_at) + (.5/24) * agent_hours.start_time * 2) + (rownum * .5/24),'HH24:mi') endtime,
to_timestamp(to_char(((trunc(starts_at) + (.5/24) * agent_hours.start_time * 2) + ((rownum -1) * .5/24)),'DD-MON-YYYY HH24:MI:SS'),'DD-MON-YYYY HH24:MI:SS') full_starttime,
to_timestamp(to_char(((trunc(starts_at) + (.5/24) * agent_hours.start_time * 2) + (rownum * .5/24)),'DD-MON-YYYY HH24:MI:SS'),'DD-MON-YYYY HH24:MI:SS') full_endtime,
starts_at,
ends_at
from agent_hours,
( select rownum
from all_objects
where rownum <= (select end_time - start_time from agent_hours)*2) ) slots
where slots.agent_id = app.agent_id(+);
您能提供Starts_AT和Ends_AT的数据类型吗?Starts_AT和Ends_AT是时间戳;id和agent_id是数字我在最后一行sql Developer中运行此命令时,仍然没有正确结束sql命令我不得不留下实际细节的原因是,为了获得代理计划,我必须加入4个表,并将代理与约会关联,然后加入另外4个表。谢谢你给它一个镜头,即使是最小的细节。完美的,谢谢你。我完全可以将其扩展到我们复杂的商业模式。最好的扩展方法是什么,以允许日程安排不均匀地结束?我的意思是,如果代理的日程安排从上午9:00开始,但在下午5:15到17:00结束,我不希望时段超过日程安排的结束时间。另外,slots.agent\u id=app.gent\u id+中的+用于什么?不管有没有,我都得到了同样的结果?再次感谢。slots.agent\u id=app.agent\u id+是一个外部连接。即使没有代理预约,也会始终返回插槽信息。