首页 新闻 会员 周边

怎样合并成时间段,数据是从数据库里查询出来的,各行之间是没有任何规律的

0
悬赏园豆:5 [已解决问题] 解决于 2014-10-26 20:53

举个例子,这个合并成就是,就是要找出连续的时间段 2014-9-19 1:10 to 2014-9-19 1:43 和  2014-9-19 1:50 到  2014-9-19 1:55

开始时间           结束时间

2014-9-19 1:10   2014-9-19 1:40            

2014-9-19 1:20   2014-9-19 1:43             

2014-9-19 1:39   2014-9-19 1:42            

2014-9-19 1:50   2014-9-19 1:55  ..........................

            数据是从数据库里查询出来的,各行之间是没有任何规律的,只是每一行的结束时间大于开始时间

999999999999999的主页 999999999999999 | 初学一级 | 园豆:3
提问于:2014-09-20 11:46
< >
分享
最佳答案
0

1、你的原始数据是什么格式?

2、什么叫连续的时间段?给个清晰的定义。

收获园豆:5
519740105 | 大侠五级 |园豆:5810 | 2014-09-20 12:47

1.原始数据就是这样的, 2014-9-19 1:10 就是日期格式,具体到分钟

2.连续的表示时间时间挨着的,没有间隙,如

2014-9-19 1:10   2014-9-19 1:40就表示  2014-9-19 1:10到2014-9-19 1:40

2014-9-19 1:20   2014-9-19 1:43 表示2014-9-19 1:20 到 2014-9-19 1:43

2014-9-19 1:30   2014-9-19 1:37

2014-9-19 1:50   2014-9-19 1:55表示2014-9-19 1:50到   2014-9-19 1:55

,合起来就是

2014-9-19 1:10到  2014-9-19 1:43  和 2014-9-19 1:50到   2014-9-19 1:55,当然我的数据是任意的

999999999999999 | 园豆:3 (初学一级) | 2014-09-20 14:00

2、什么叫连续的时间段?给个清晰的定义。

 

就是时间重叠的合并起来,合并成时间段

999999999999999 | 园豆:3 (初学一级) | 2014-09-20 14:02

@999999999999999: 明白了。

要把记录B跟记录A合并,那么:

1、判断记录B的起始日期或终止日期是否在A的时间段内

2、合并后的时间段是AB的最小起始时间为起始时间,AB的最大终止时间为终止时间。

操作起来有点麻烦,代码有点复杂,建议最好使用临时表来实现这个功能。用简单的SQL是不能实现的,而用复杂的语句实现起来,逻辑也将过于复杂。

519740105 | 园豆:5810 (大侠五级) | 2014-09-20 17:01

@519740105: 我是用C#后台实现,

2、合并后的时间段是AB的最小起始时间为起始时间,AB的最大终止时间为终止时间。 因为可能交叉,可能完全包含,可能完全不包含,这里应该有个算法

没这么简单,我想了很久

因为查询出来的数据时任意的

如A : 2014-9-20 08:20 --2014-9-20 09:20

B:     2014-9-20 08:30 --2014-9-20 09:10 合并后是:2014-9-20 08:20 --2014-9-20 09:20 

如A : 2014-9-20 08:20 --2014-9-20 09:20

B:     2014-9-20 08:10 --2014-9-20 09:00 合并后是:2014-9-20 08:10 --2014-9-20 09:20

如A : 2014-9-20 08:20 --2014-9-20 09:20

B:     2014-9-20 09:30 --2014-9-20 09:40 合并后是:

 2014-9-20 08:20 --2014-9-20 09:20 和

2014-9-20 09:30 --2014-9-20 09:40 

 

再下一条C:又要和前面比较出的结果记录每条比较,C和前面每条比较出的时间段,可能增加一条,可能合并成只有一个时间段,可能交叉

999999999999999 | 园豆:3 (初学一级) | 2014-09-20 20:28

@999999999999999: 

如果用C#,那就更简单了:

方案一:

1、定义一个结构(类)记录你的数据信息。

2、逐条数据查找,如果数据归类于前一个,则合并,置该数据为删除状态(或直接删除)

3、得到最终结果

参考代码:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    public class Node
    {
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public bool Deleted { get; set; }
    }

    public class Test
    {
        private DateTime Min(DateTime v1, DateTime v2)
        {
            if (v1 > v2)
            {
                return v2;
            }
            return v1;
        }

        private DateTime Max(DateTime v1, DateTime v2)
        {
            if (v1 > v2)
            {
                return v1;
            }
            return v2;
        }

        public IList<Node> Run(IList<Node> list)
        {
            list = list.OrderBy(x=>x.StartTime).ToList();
            for (int i = 0; i < list.Count - 1; i++)
            {
                if (list[i].Deleted)
                {
                    continue;
                }
                for(int j = i + 1; j < list.Count; j++)
                {
                    if ((list[j].StartTime >= list[i].StartTime && list[j].StartTime <= list[i].EndTime) || (list[j].EndTime >= list[i].StartTime && list[j].EndTime <= list[i].EndTime))
                    {
                        list[i].StartTime = Min(list[i].StartTime, list[j].StartTime);
                        list[i].EndTime = Max(list[i].EndTime, list[j].EndTime);
                        list[j].Deleted = true;
                    }
                }
            }
            return list.Where(x => !x.Deleted).ToList();
        }
    }
}

 

至于方案二,可以形成树,这样能不影响原始数据。这里就不多写了。

而方案一,也是有需要优化的,但是,除非你的数据量很大,这个优化价值也不大。

519740105 | 园豆:5810 (大侠五级) | 2014-09-20 22:10
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册