- 浏览: 43564 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
lost_alien:
复杂的sql恐怕用这个就够呛了。。。。
DSL-SQL源码分析 -
liaobinxu:
shaopei3344 写道递归不是会引起栈溢出吗。说说递归在 ...
递归算法 -
shaopei3344:
递归不是会引起栈溢出吗。
说说递归在现实中的例子
递归算法
问题:Leonard C.Medal在许多年前提出了很多了这个技巧问题。 在医院的手术室中, 麻醉师为手术中的病人实行麻醉。 每个人麻醉过程的信息都记录在一个表中。
[list]
注意抹嘴是的某些时间是重叠的, 这不是错误。 麻醉师跟外科医生不同, 他可以在手术过程中从一个手术室走到另一个手术室,依次检查每一个病人, 调整药的计量, 留下实习医生和护士时刻监察病人的情况。
麻醉师的工资按照麻醉过程数量支付, 但是计算方法很复杂。 根据麻醉师同时负责的麻醉过程的最大数量, 为每个麻醉过程二支付给麻醉师的报酬是浮动的。 麻醉工程越多, 为每个过程支付的报酬就越少。
问题就成为对于每一个人进行中的麻醉过程, 确定每一个麻醉师同时进行麻醉过程的最大即时数目。
我们通过可以通过图形到处答案,以便更好的理解问题。
proc_id max_inst_count
------------------------------------------------
10 2
20 2
30 3
40 3
50 3
60 3
70 2
80 1
向procs表插入数据
-- PROC_ID ANEST_NAME START_TIME END_TIME
--------------------------------------- ---------------------------------------- ----------- -----------
-- 10 'Baker' 08:00:00 11:00:00
-- 20 'Baker' 09:00:00 13:00:00
-- 30 'Dow' 09:00:00 15:30:00
-- 40 'Dow' 08:00:00 13:30:00
-- 50 'Dow' 10:00:00 11:30:00
-- 60 'Dow' 12:30:00 13:30:00
-- 70 'Dow' 13:30:00 14:30:00
-- 80 'Dow' 18:00:00 19:30:00
--方法1
如果显示权限不足, 请登入sys账号,并以as sysdba方式登录 然后授权view给scott // grant create view to scott;
说明:用数学知识:not ((p2.end_time<=p1.start_time or p2.start_time>=p1.end_time) )等价于 p2.end_time>p1.start_time and p2.start_time <p1.end_time,意思是p2
--的时间段在p1的时间段的真子集(不包括两端)
方法2
结果
PROC_ID MAX(CONCURRENTPROCS.TALLY)
--------------------------------------- --------------------------
30 3
20 2
70 2
40 3
50 3
80 1
10 2
60 3
解析上面这个复杂的查询
首先查看它的子查询, 分为几步
step 1
结果是
ANEST_NAME TO_CHAR(P1.START_TIME,'HH24:MI COUNT(*)
---------------------------------------- ------------------------------ ----------
Baker 09:00:00 2
Dow 13:30:00 2
Dow 08:00:00 1
Dow 12:30:00 3
Dow 10:00:00 3
Baker 08:00:00 1
Dow 09:00:00 2
Dow 18:00:00 1
step 2
对step 1 的查询在进行分解
得到的查询结果
P1ID P2ID P1ANEST_NAME P2ST P1ST P2ET
--------------------------------------- --------------------------------------- ---------------------------------------- -------- -------- --------
10 10 Baker 08:00:00 08:00:00 11:00:00
20 10 Baker 08:00:00 09:00:00 11:00:00
20 20 Baker 09:00:00 09:00:00 13:00:00
30 30 Dow 09:00:00 09:00:00 15:30:00
30 40 Dow 08:00:00 09:00:00 13:30:00
40 40 Dow 08:00:00 08:00:00 13:30:00
50 50 Dow 10:00:00 10:00:00 11:30:00
50 40 Dow 08:00:00 10:00:00 13:30:00
50 30 Dow 09:00:00 10:00:00 15:30:00
60 30 Dow 09:00:00 12:30:00 15:30:00
60 40 Dow 08:00:00 12:30:00 13:30:00
60 60 Dow 12:30:00 12:30:00 13:30:00
70 70 Dow 13:30:00 13:30:00 14:30:00 70 30 Dow 09:00:00 13:30:00 15:30:00
80 80 Dow 18:00:00 18:00:00 19:30:00
得到一个结论: 就是在同意麻醉师的情况下, 找到一组其中p1的启动时间在p2在开始之后(包括开始时刻)、在p2结束之前,这样的到的结果p1就是和其他麻醉记录(包括自己)有交集的。然后在在一proc_id,anest_name 分组,就可以得到和其他记录有时间相交的记录(但是并不是相交记录的最大数目)
step 3
结果
PROC_ID MAX(CONCURRENTPROCS.TALLY)
--------------------------------------- --------------------------
30 3
20 2
70 2
40 3
50 3
80 1
10 2
60 3
结论: step 2中找到的集合p1的就是step 3的视图ConcurrentProcs,而p3.start_time<=ConcurrentProcs.start_time and p3.end_time> ConcurrentProcs.start_time这两个条件表示找到一个集合p3能够在p1发生和p1结束之前发生(p1和任何记录都有时间交集的麻醉记录),等价于和任何都有交集的集合有相交的集合的条件下,取相交数量的最大值, 就是确定每一个麻醉师同时进行麻醉过程的最大即时数目
方法3
想法是在所有的麻醉记录过程中(p1)进行循环;对于每一个麻醉过程p1, 查找其起始时间落在麻醉过程p1中的麻醉过程p2. 对于找到的每一个p2的起始时间,计算该时间正在进行的麻醉过程(p3)的数目。然后,去出麻醉过程p1的最大计数。
然后对每一过程取最大值:
select id1 proc_id, max(total) max_inst_count from Vprocs group by id1;
结果是
PROC_ID MAX_INST_COUNT
--------------------------------------- --------------
30 2
70 1
20 1
50 2
40 2
60 2
10 1
共有七项记录
结果有问题: 应该选取八项:
[list]
引用
procs
proc_id anest_name start_time end_time
----------------------------------------------------------------------------
10 'Baker' 08:00 11:00
20 'Baker' 09:00 13:00
30 'Dow' 09:00 15:30
40 'Dow' 08:00 13:30
50 'Dow' 10:00 11:30
60 'Dow' 12:30 13:30
70 'Dow' 13:30 14:30
80 'Dow' 18:00 19:00
proc_id anest_name start_time end_time
----------------------------------------------------------------------------
10 'Baker' 08:00 11:00
20 'Baker' 09:00 13:00
30 'Dow' 09:00 15:30
40 'Dow' 08:00 13:30
50 'Dow' 10:00 11:30
60 'Dow' 12:30 13:30
70 'Dow' 13:30 14:30
80 'Dow' 18:00 19:00
注意抹嘴是的某些时间是重叠的, 这不是错误。 麻醉师跟外科医生不同, 他可以在手术过程中从一个手术室走到另一个手术室,依次检查每一个病人, 调整药的计量, 留下实习医生和护士时刻监察病人的情况。
麻醉师的工资按照麻醉过程数量支付, 但是计算方法很复杂。 根据麻醉师同时负责的麻醉过程的最大数量, 为每个麻醉过程二支付给麻醉师的报酬是浮动的。 麻醉工程越多, 为每个过程支付的报酬就越少。
问题就成为对于每一个人进行中的麻醉过程, 确定每一个麻醉师同时进行麻醉过程的最大即时数目。
我们通过可以通过图形到处答案,以便更好的理解问题。
proc_id max_inst_count
------------------------------------------------
10 2
20 2
30 3
40 3
50 3
60 3
70 2
80 1
--创建一个sequence proc_sequence create sequence proc_sequence increment by 10 start with 10 nomaxvalue nocycle noorder; --创建一个procs表 create table procs( proc_id integer not null primary key, anest_name varchar2(40) not null, start_time date not null, end_time date not null );
向procs表插入数据
-- PROC_ID ANEST_NAME START_TIME END_TIME
--------------------------------------- ---------------------------------------- ----------- -----------
-- 10 'Baker' 08:00:00 11:00:00
-- 20 'Baker' 09:00:00 13:00:00
-- 30 'Dow' 09:00:00 15:30:00
-- 40 'Dow' 08:00:00 13:30:00
-- 50 'Dow' 10:00:00 11:30:00
-- 60 'Dow' 12:30:00 13:30:00
-- 70 'Dow' 13:30:00 14:30:00
-- 80 'Dow' 18:00:00 19:30:00
insert into procs values( proc_sequence.nextval,'Baker',to_date('2009-3-22 08:00','yyyy-mm-dd hh24:mi'), to_date('2009-3-22 11:00','yyyy-mm-dd hh24:mi')); insert into procs values( proc_sequence.nextval,'Baker',to_date('2009-3-22 09:00','yyyy-mm-dd hh24:mi'), to_date('2009-3-22 13:00','yyyy-mm-dd hh24:mi')); insert into procs values( proc_sequence.nextval,'Dow',to_date('2009-3-22 09:00','yyyy-mm-dd hh24:mi'), to_date('2009-3-22 15:30','yyyy-mm-dd hh24:mi')); insert into procs values( proc_sequence.nextval,'Dow',to_date('2009-3-22 08:00','yyyy-mm-dd hh24:mi'), to_date('2009-3-22 13:30','yyyy-mm-dd hh24:mi')); insert into procs values( proc_sequence.nextval,'Dow',to_date('2009-3-22 10:00','yyyy-mm-dd hh24:mi'), to_date('2009-3-22 11:30','yyyy-mm-dd hh24:mi')); insert into procs values( proc_sequence.nextval,'Dow',to_date('2009-3-22 12:30','yyyy-mm-dd hh24:mi'), to_date('2009-3-22 13:30','yyyy-mm-dd hh24:mi')); insert into procs values( proc_sequence.nextval,'Dow',to_date('2009-3-22 13:30','yyyy-mm-dd hh24:mi'), to_date('2009-3-22 14:30','yyyy-mm-dd hh24:mi')); insert into procs values( proc_sequence.nextval,'Dow',to_date('2009-3-22 18:00','yyyy-mm-dd hh24:mi'), to_date('2009-3-22 19:30','yyyy-mm-dd hh24:mi'));
--方法1
如果显示权限不足, 请登入sys账号,并以as sysdba方式登录 然后授权view给scott // grant create view to scott;
create view Events (proc_id,comparison_proc, anest_name,event_time,event_type) as select p1.proc_id,p2.proc_id,p1.anest_name,p2.start_time,+1 from procs p1, procs p2 where p1.anest_name=p2.anest_name union select p1.proc_id, p2.proc_id, p1.anest_name,p2.end_time,-1 from procs p1, procs p2 where p1.anest_name=p2.anest_name and not (p2.end_time<=p1.start_time or p2.start_time>=p1.end_time);
说明:用数学知识:not ((p2.end_time<=p1.start_time or p2.start_time>=p1.end_time) )等价于 p2.end_time>p1.start_time and p2.start_time <p1.end_time,意思是p2
--的时间段在p1的时间段的真子集(不包括两端)
方法2
select p3.proc_id , max(ConcurrentProcs.tally) from (select p1.anest_name anest_name, p1.start_time start_time, count(*) tally from procs p1 inner join procs p2 on p1.anest_name=p2.anest_name and p2.start_time<=p1.start_time and p2.end_time>p1.start_time group by p1.anest_name, p1.start_time )ConcurrentProcs--(anest_name,start_time, tally) inner join procs p3 on ConcurrentProcs.anest_name=p3.anest_name and p3.start_time<=ConcurrentProcs.start_time and p3.end_time> ConcurrentProcs.start_time group by p3.proc_id
结果
PROC_ID MAX(CONCURRENTPROCS.TALLY)
--------------------------------------- --------------------------
30 3
20 2
70 2
40 3
50 3
80 1
10 2
60 3
解析上面这个复杂的查询
首先查看它的子查询, 分为几步
step 1
select p1.anest_name , to_char(p1.start_time,'hh24:mi:ss'), count(*) from procs p1 inner join procs p2 on p1.anest_name=p2.anest_name and p2.start_time<=p1.start_time and p2.end_time>p1.start_time group by p1.anest_name, p1.start_time;
结果是
ANEST_NAME TO_CHAR(P1.START_TIME,'HH24:MI COUNT(*)
---------------------------------------- ------------------------------ ----------
Baker 09:00:00 2
Dow 13:30:00 2
Dow 08:00:00 1
Dow 12:30:00 3
Dow 10:00:00 3
Baker 08:00:00 1
Dow 09:00:00 2
Dow 18:00:00 1
step 2
对step 1 的查询在进行分解
select p1.proc_id P1ID,p2.proc_id P2ID,p1.anest_name P1ANEST_NAME , to_char(P2.start_time,'hh24:mi:ss') P2ST, to_char(p1.start_time,'hh24:mi:ss') P1ST, to_char(p2.end_time,'hh24:mi:ss') P2ET from procs p1 inner join procs p2 on p1.anest_name=p2.anest_name and p2.start_time<=p1.start_time and p2.end_time>p1.start_time order by p1.proc_id
得到的查询结果
P1ID P2ID P1ANEST_NAME P2ST P1ST P2ET
--------------------------------------- --------------------------------------- ---------------------------------------- -------- -------- --------
10 10 Baker 08:00:00 08:00:00 11:00:00
20 10 Baker 08:00:00 09:00:00 11:00:00
20 20 Baker 09:00:00 09:00:00 13:00:00
30 30 Dow 09:00:00 09:00:00 15:30:00
30 40 Dow 08:00:00 09:00:00 13:30:00
40 40 Dow 08:00:00 08:00:00 13:30:00
50 50 Dow 10:00:00 10:00:00 11:30:00
50 40 Dow 08:00:00 10:00:00 13:30:00
50 30 Dow 09:00:00 10:00:00 15:30:00
60 30 Dow 09:00:00 12:30:00 15:30:00
60 40 Dow 08:00:00 12:30:00 13:30:00
60 60 Dow 12:30:00 12:30:00 13:30:00
70 70 Dow 13:30:00 13:30:00 14:30:00 70 30 Dow 09:00:00 13:30:00 15:30:00
80 80 Dow 18:00:00 18:00:00 19:30:00
得到一个结论: 就是在同意麻醉师的情况下, 找到一组其中p1的启动时间在p2在开始之后(包括开始时刻)、在p2结束之前,这样的到的结果p1就是和其他麻醉记录(包括自己)有交集的。然后在在一proc_id,anest_name 分组,就可以得到和其他记录有时间相交的记录(但是并不是相交记录的最大数目)
step 3
select p3.proc_id , max(ConcurrentProcs.tally) from (select p1.anest_name anest_name, p1.start_time start_time, count(*) tally from procs p1 inner join procs p2 on p1.anest_name=p2.anest_name and p2.start_time<=p1.start_time and p2.end_time>p1.start_time group by p1.anest_name, p1.start_time )ConcurrentProcs--(anest_name,start_time, tally) inner join procs p3 on ConcurrentProcs.anest_name=p3.anest_name and p3.start_time<=ConcurrentProcs.start_time and p3.end_time> ConcurrentProcs.start_time group by p3.proc_id
结果
PROC_ID MAX(CONCURRENTPROCS.TALLY)
--------------------------------------- --------------------------
30 3
20 2
70 2
40 3
50 3
80 1
10 2
60 3
结论: step 2中找到的集合p1的就是step 3的视图ConcurrentProcs,而p3.start_time<=ConcurrentProcs.start_time and p3.end_time> ConcurrentProcs.start_time这两个条件表示找到一个集合p3能够在p1发生和p1结束之前发生(p1和任何记录都有时间交集的麻醉记录),等价于和任何都有交集的集合有相交的集合的条件下,取相交数量的最大值, 就是确定每一个麻醉师同时进行麻醉过程的最大即时数目
方法3
想法是在所有的麻醉记录过程中(p1)进行循环;对于每一个麻醉过程p1, 查找其起始时间落在麻醉过程p1中的麻醉过程p2. 对于找到的每一个p2的起始时间,计算该时间正在进行的麻醉过程(p3)的数目。然后,去出麻醉过程p1的最大计数。
create view Vprocs(id1,id2,total) as select p1.proc_id,p2.proc_id,count(*) from procs p1, procs p2, procs p3 where p2.anest_name=p1.anest_name and p3.anest_name=p1.anest_name and p1.start_time<=p2.start_time and p1.start_time<p2.end_time and p3.start_time<p2.start_time and p2.start_time<p3.end_time group by p1.proc_id,p2.proc_id;
然后对每一过程取最大值:
select id1 proc_id, max(total) max_inst_count from Vprocs group by id1;
结果是
PROC_ID MAX_INST_COUNT
--------------------------------------- --------------
30 2
70 1
20 1
50 2
40 2
60 2
10 1
共有七项记录
结果有问题: 应该选取八项:
- 麻醉师问题.zip (12.4 KB)
- 下载次数: 6
相关推荐
标题中的“sql解惑-跟踪投资组合问题”指的是在数据库管理中,特别是在SQL查询中解决与投资组合管理相关的复杂问题。投资组合问题通常涉及到金融数据分析,包括股票、债券和其他金融资产的投资组合表现、风险评估...
引入sql-map-config-2.dtd后,开发者可以确保配置文件的语法正确,避免因格式错误导致的运行时问题。 在实际应用中,这两个DTD文件通常会被引用到对应的XML配置文件顶部,如下所示: ```xml <!DOCTYPE sqlMap ...
x-pack-sql-jdbc-6.4.0到x-pack-sql-jdbc-7.6.0各个版本jdbc驱动下载
SQL Server 2019 正式版安装引导介质,可下载ISO到本地进行安装。不支持Windows7及以下系统安装。
x-pack-sql-jdbc-6.5.4.jar
flume-ng-sql-source-1.5.2.jar从数据库中增量读取数据到hdfs中的jar包
SQLPrompt-10.14.0.4064.exe 支持SSMS 19.1
通过阅读《SQL解惑 第二版》,读者不仅能够理解SQL的基本语法,还能学会如何在实际工作中有效利用SQL解决问题。书中的案例分析使学习过程更为直观,对于初学者和有一定经验的数据库管理员来说,都是一份极好的学习...
flume-ng-sql-source-1.5.1 flume连接数据库 很好用的工具
sqldeveloper-17.2.0.188.1159-x64.zip oracle mysql 数据库,适合Windows系统,可以链接mysql是一款不错的数据库x64
针对每个问题的解决方案均遵循SQL-99标准以及后续的相关标准,这不仅保证了解决方案的前沿性和实用性,也反映出作者对SQL语言及其发展趋势的深刻认识。书中所探讨的问题几乎涵盖了SQL语言的各个方面,包括但不限于...
sql server-练习卷-问题修改.sql
根据提供的标题、描述以及部分上下文内容,我们可以推断出这本书《SQL解惑(中文版)》主要聚焦于SQL技能的提升与深化理解。虽然实际的内容并未给出具体示例或章节概述,但根据书名及简介,我们可以围绕SQL的基础...
《SQL解惑(第2版)》是一本深入探讨SQL编程问题的专业书籍,旨在帮助读者解决在实际工作中遇到的各种SQL难题。SQL,全称为Structured Query Language,是用于管理和处理关系数据库的标准语言。这本书以问题为导向,...
SQL解惑解惑,意味着我们将深入探讨SQL的常见问题、概念以及解决策略。在这个过程中,我们不仅要理解SQL的基本语法,还要掌握如何有效地查询、更新和管理数据。 首先,让我们从SQL的基础开始。SQL分为四大主要部分...
资源名称:收获,不止SQL优化--抓住SQL的本质作者简介:梁敬彬,福富研究院副理事长、公司唯一四星级内训师。不仅是公司特级专家也是国内一线知名数据库专家,其个人及团队在数据库优化和培训领域有着丰富的经验、...
squirrel-sql-3.8.1-standard.jar squirrel-sql-3.8.1-standard.jar
这个压缩包“azkaban-sql-script-2.5.0.tar.gz”包含的是Azkaban 2.5.0版本的SQL脚本,这些脚本可能用于在数据库中设置和配置Azkaban所需的表结构和权限。以下将详细介绍Azkaban的关键概念、功能以及与SQL脚本的关系...
根据提供的文件信息,此文档的标题是“sql解惑.pdf”,描述为“个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!”,标签为“计算机 编程”,而部分内容实际上并未提供与SQL相关的有效...