现在有一个系统他十四个子模块,要求的是这个系统的停止时间,现在在一个表中记录着每一个子模块的停止时间,只要有一个子模块停止了,表里就会多一条关于子模块停止的开始时间、结束时间和子模块代码的记录。子模块停止就代表系统停止。现在要求一个周内系统的停止的时间。请问这个逻辑应该怎么写。注意的是如果子模块1停止时间为八点到九点,子模块2停止的时间为八点半到九点半,那么系统的停止时间是八点到九点半,要排除重复时间,请大神表述的详细一点,本人小白,不太懂这个o(╯□╰)o
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率

小白请教一个sql逻辑的问题,详见问题描述
收起
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
微信扫一扫
点击复制链接分享
- 邀请回答
- 编辑 收藏 删除 结题
- 收藏 举报
当前问题酬金
¥ 0 (可追加 ¥500)
支付方式
扫码支付
14条回答 默认 最新
- 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
qq221746 2016-09-12 09:19关注--看一下我理解的对不对
DECLARETYPE t_table IS TABLE OF 记录表%ROWTYPE;
v_data t_table;
v_second INTEGER:=0;
v_begin DATE;
v_end DATE;
BEGIN
SELECT * BULK COLLECT INTO v_data FROM 记录 ORDER BY 开始时间,结束时间 WHERE 开始时间>=sysdate-7;
FOR i IN 1..v_data.count LOOP
IF i=1 THEN
v_begin:=v_data(i).开始;
v_end:=v_data(i).结束;
ELSE
IF v_data(i).开始<v_data(i-1).结束 THEN
v_begin:=v_data(i-1).结束;
ELSE
v_begin:=v_data(i).开始;
END IF;
v_end:=v_data(i).结束;
END IF;
v_second:=(v_end-v_begin)*24*60*60+v_second;
END LOOP;
END;本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容
- 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
qq_34906828 2016-09-12 08:41关注急急急!拜托各位大神了!!小弟感激不尽!!!
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
qq221746 2016-09-12 08:43关注所有子模块都停止,系统才算停止吗?
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
海_贼-王 2016-09-12 08:43关注得确认:系统的停止时间是什么
1、如果系统的停止时间是指所有的模块都停止,最后一个模块停止时候的停止时间;
那么直接看数据库中是否有14条记录,如果有,那么根据结束时间(肯定含日期的)倒序排列获取第一条就好了,没有就是系统没停止。2、如果系统的停止时间,是指每天最后一个停止模块的结束时间,那么
先将所有的停止时间按天归类,然后在每个分类中将结束时间倒序排列,取第一个 。如果某天内没有数据,就是当天系统没停止。本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
qq221746 2016-09-12 08:48关注select min(开始时间),max(停止时间) from 记录表 where 开始时间>=sysdate-7
呵呵 那么简单吗? 我是不是理解错了
是不是区间问题? 比如1点到2点
5点到8点10点到12点?
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
zhaihonghonghzh 2016-09-12 09:20关注看你描述 应该是有时间间隔的是吗
先查询出来这一周内的记录 然后把开始时间和结束时间都取出来放到一个集合中进行时间判断本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
zhaihonghonghzh 2016-09-12 09:21关注查询时按着开始时间排序
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
觅夜的黑 2016-09-12 09:32关注做一个排序,然后判断第二个开始时间是否在第一个的里面,如果在,直接取第二个的结束时间。 不在就分别计算。
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
qq221746 2016-09-12 10:02关注SELECT SUM(times) FROM (
select b.*,case
when bd >= pre_end then
ed - bd
else
ed - pre_end
END AS times
from (select lag(a.ed, 1, a.bd) over(order by bd, bd) pre_end,a.*
from 表名 a
order by bd, ed) b)对应sql可以这么写,用lag开窗函数 bd 开始时间 ed 结束时间 有点绕 可能还不如我上面写的代码块好理解
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
Mop.Duan 2016-09-12 10:42关注Oracle 存储过程可以解决:整体思路,不需要区分具体是哪个模块,把所有数据停止开始时间dtimes倒序进行遍历,记录最终开始日期maxdate和最终结束日期mindate,同事记录不存在的时候不交叉的时间段秒数removetime;最终用maxdate和mindate的秒数减去removetime的秒数,即为停止总时间(秒)。
==============存储过程===prm_today某天日期 参数格式2016-01-01 返回的是秒数 (查询一周的话自己改下代码即可,本例查询某天数据)========================
create or replace procedure TestDuan(prm_today IN VARCHAR2,PRM_allTime out NUMBER) is
maxdate date ;
mindate date;
removetime number;
temptime number;
temp number;
CURSOR CUR_TABLE IS
SELECT * FROM DTEST where dtimes >= to_date(prm_today||' 00:00:00','yyyy-mm-dd HH24:mi:ss')
and dtimee <= to_date(prm_today||' 00:00:00','yyyy-mm-dd HH24:mi:ss') order by dtimes;
begin
maxdate:=null;
maxdate:=null;
temp:=0;
removetime:=0;
FOR REC_table IN CUR_TABLE LOOP
if temp=0 then
temp:=1;
mindate := REC_table.Dtimes;
maxdate := REC_table.Dtimee;
end if;
if REC_table.Dtimes<=maxdate and REC_table.Dtimee<=maxdate then
removetime :=removetime;
elsif REC_table.Dtimes<=maxdate and REC_table.Dtimee>=maxdate then
maxdate :=REC_table.Dtimee;
elsif REC_table.Dtimes>=maxdate then
SELECT TO_NUMBER(REC_table.Dtimes-maxdate) * 24 * 60 * 60 into temptime FROM DUAL;
removetime :=removetime+temptime;
maxdate :=REC_table.Dtimee;
end if;
END LOOP;
SELECT TO_NUMBER(maxdate-mindate) * 24 * 60 * 60 into PRM_allTime FROM DUAL;
PRM_allTime:=PRM_allTime - removetime;
end TestDuan;
====================Table==================================
====================运行结果================================本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
关注
如果你有模块的停止时间都保存在一个表中,支持 @qq221746 的回答
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
海_贼-王 2016-09-13 00:59关注假定你有类A { start_time , end_time}
1、将数据库所有数据取出放到list;
2、定义一个LinkedList 用来存放最终处理之后的 无重复,无间隔的时间段 , 处理时保证时间段递增。
3、定义一个比较方法
compareA(A a,LinkedList b){
1、如果b的大小为0则将a放到b中
2、如果b的大小大于0,则将a的时间间隔依次与b中的进行比较
比较逻辑:a与b.get(i)比较 注意:**(int i=0;i<=b.size();) 这里最后i<=b.size(),是为了最后的处理,且i++要在逻辑中自己加**
1、如果a的结束时间小于b.get(i)的开始时间,则把a插入到b.get(i)的前面,return b。
2、如果a的开始时间大于b.get(i)的结束时间,
如果i=b.size()-1则将a插入到b的最后面,return b;
如果i<b.size()-1则i++进入下一个循环,
3、如果a与b.get(i)有交集,则将a与b.get(i)的时间集合求并集,将并集的开始结束时间赋值给a,然后从b中remove掉第i个元素,
然后直接进入下一个循环,不要进行i++
4、结束处理,如果i==b.size(),则将a添加到b的最后面
}上面逻辑就这样了。 如果编码有什么问题,再询问。 希望对你有帮助!
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
海_贼-王 2016-09-13 02:35关注如果你懂java的话,就使用下我下面的代码吧 。
package zzQuestions;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;public class TimeRemoveMulti {
/** * 现在有一个系统他十四个子模块,要求的是这个系统的停止时间, * 现在在一个表中记录着每一个子模块的停止时间,只要有一个子模块停止了, * 表里就会多一条关于子模块停止的开始时间、结束时间和子模块代码的记录。 * 子模块停止就代表系统停止。现在要求一个周内系统的停止的时间。请问这个逻辑应该怎么写。 * 注意的是如果子模块1停止时间为八点到九点,子模块2停止的时间为八点半到九点半, * 那么系统的停止时间是八点到九点半,要排除重复时间 * 系统的停止时间是如果一个子模块出现了停止,那么这个子模块的停止时间就要算到系统的停止时间里面, * 最后要统计的是每周的工作时间, * 所以不能是单纯的每个子模块的停止时间求和,要剔除各个子模块停止时间重复的部分 * @throws ParseException */ public static void main(String args[]) throws ParseException { List<A> dataArray = new ArrayList<A>(); //存放数据库值 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dataArray.add(new A(df.parse("2016-9-10 11:23:24"), df.parse("2016-9-10 17:23:24"))); dataArray.add(new A(df.parse("2016-9-10 8:23:24"), df.parse("2016-9-10 13:23:24"))); dataArray.add(new A(df.parse("2016-9-11 11:23:24"), df.parse("2016-9-11 17:23:24"))); LinkedList<A> resultArray = new LinkedList<A>(); //存放最终无重复的时间段值 for (A a : dataArray) { //循环处理 compare(a, resultArray); } for (A a : resultArray) { //输出最后的记结果 System.out.println(df.format(a.getStartTime()) + "\t" + df.format(a.getEndTime())); } } public static void compare(A a, LinkedList<A> resultArray) { for (int i = 0; i <= resultArray.size();) { //size为0或最终结束 if (i == resultArray.size()) { resultArray.add(a); return; } A b = resultArray.get(i); //结束时间小于开始时间,插在前面返回,且不需要再与后面比较直接返回 if (a.getEndTime().before(b.getStartTime())) { resultArray.add(i, a); return; } //开始时间大于开始时间,i++进入下一次循环 if (a.getStartTime().after(b.getEndTime())) { i++; continue; } //a被b包含,则直接退出 if (a.getStartTime().after(b.getStartTime()) && a.getEndTime().before(b.getEndTime())) { return; } //a将b的第i个元素包含或者2这有交集,则将并集付给A,并且从resultArray中移除B,然后进入下一次循环 { Date startTime = a.getStartTime().compareTo(b.getStartTime()) > 0 ? b.getStartTime() : a.getStartTime(); Date endTime = a.getEndTime().compareTo(b.getEndTime()) > 0 ? a.getEndTime() : b.getEndTime(); a.setStartTime(startTime); a.setEndTime(endTime); resultArray.remove(i); continue; //写了方便看 } } } static class A { private Date startTime; private Date endTime; public A(Date startTime, Date endTime) { this.startTime = startTime; this.endTime = endTime; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } }
}
输出结果 :
2016-09-10 08:23:24 2016-09-10 17:23:24
2016-09-11 11:23:24 2016-09-11 17:23:24本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容 - 关注
码龄 粉丝数 原力等级 --
- 被采纳
- 被点赞
- 采纳率
qq221746 2016-09-14 07:56关注亲,该结贴了吧? 我就等你的c币呢
本回答被题主选为最佳回答 , 对您是否有帮助呢? 本回答被专家选为最佳回答 , 对您是否有帮助呢? 本回答被题主和专家选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏举报微信扫一扫
点击复制链接分享
评论按下Enter换行,Ctrl+Enter发表内容
报告相同问题?
悬赏问题
- ¥15 vue+element 生成table
- ¥15 实验 4 FIFO 算法和 LRU 算法-C 程序实现
- ¥30 电脑画面同步投屏,通过同wifi的方式投屏方法,接收投屏端不需要安装第三方软件,
- ¥15 有偿拼接大疆精灵4RGB影像
- ¥15 MATLAB特殊符号
- ¥15 Arduino实现音频混响
- ¥15 cuda.jit加速报错
- ¥15 Octave 安装工具箱出错 Only Win32 target is supported!
- ¥15 docker save的不能在另一台设备运行
- ¥15 Unity Animation Rigging使用问题