Php 总结所有时间段

Php 总结所有时间段,php,mysql,Php,Mysql,我有一个表,其中有两列包含特定事件的time_from和time_to。两列的类型都是TINYINT2。例如 id time_from time_to __________________________ 11 8 14 18 12 17 44 20 24 有些时期重叠。我需要总结所有的时间,并确保我不重复计算重叠的时间 不幸的是,我无法更改列类型,必须使用现有的列类型。我该怎

我有一个表,其中有两列包含特定事件的time_from和time_to。两列的类型都是TINYINT2。例如

id    time_from    time_to
__________________________
11       8            14
18       12           17    
44       20           24
有些时期重叠。我需要总结所有的时间,并确保我不重复计算重叠的时间

不幸的是,我无法更改列类型,必须使用现有的列类型。我该怎么做

预期结果如下:

14 - 8 = 6
17 - 12 = 5
24-20 = 4
重叠时间为2小时12-14

总计:6+5+4-2=13

我假设您的time\u from和time\u to列表示1到24之间的小时

编辑。正如你澄清的,我假设20,24包括四个小时,也就是说,20,21,22,23。每个范围不包括最后提到的小时:[20,24

你可以用序列表来解决这个问题,就是这样

在MariaDB中,它是内置的:表seq_1_至_24就是它

像这样将它与您的另一个表连接起来,您的另一个表的每一行每小时都会有一行

这是MariaDB的样子

SELECT COUNT(DISTINCT seq) hours
FROM (
SELECT seq.seq
  FROM seq_1_to_24 seq
   JOIN times t ON seq.seq >= t.time_from 
               AND seq.seq <  t.time_to
 ) a

以下解决方案假定时间_from和时间_to均按升序排序,并且重叠仅发生在相邻行之间:

# Without touching the `id` column, I create a sequential column `my_id`, assuming that the name of the  table is `times`:

alter table times add my_id int(3) not null after id;
SET @count = 0;
UPDATE times SET my_id = @count:= @count + 1;

# I use a temporary table `times2` that starts with the second row of the `times_from` column; Here, 9999 can be any large enough number:

create temporary table times2 as select my_id, time_from from times limit 1, 9999;

# Now I add a new column `time_end` to the original table. I update it with data from `time_from` column but 'shifted' by one row upwards:

alter table times add time_end int(2) not null;
update times a join times2 b on a.my_id = (b.my_id - 1) set a.time_end = b.time_from;

# Ensure that the value of `time_end` in the last row is not zero:

update times set time_end = time_to order by my_id desc limit 1;

# The required value is taken by using the minimum of columns `time_from` and `time_end`:

select sum(LEAST(time_to,time_end) - time_from) from times;

# Uncomment below to clean up just after getting the results:
    # alter table times drop column my_id;
    # alter table times drop column time_end;  

那么您在这里显示的预期输出是什么呢?6+5+4或6+2+4忽略12、13和14,因为id 11包含它?或者其他什么?@chris85我已经更新了我的帖子。我确实想数一数12、13和14,但只数一次。这很好!20-24小时是开始-结束范围,所以它只有4小时。您的说明不清楚一天的时间00:00-00:59。我的解决方案在计算时间的方式上肯定有缺陷。我的序列表可能需要0来代替24。课程:仔细说明的重要性。这远远超出了我的技能水平,太酷了!谢谢。P.S>我从未听说过mariaDB,但它看起来相当令人印象深刻。拥有您的选择绝对是个好主意这是众所周知的。我认为,在你提问之前,这远远超出了你的技能水平。现在是你的技能水平了!不客气。无论如何,在使用SQL时,请考虑Venn意义上的数据集。
SELECT COUNT(DISTINCT seq) hours
FROM (
SELECT seq.seq, t.*
  FROM (
          SELECT 1 seq UNION ALL SELECT 2  UNION ALL SELECT 3  UNION ALL SELECT 4  UNION ALL SELECT 5
                       UNION ALL SELECT 6  UNION ALL SELECT 7  UNION ALL SELECT 8  UNION ALL SELECT 9
                       UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13
                       UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 UNION ALL SELECT 17
                       UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20 UNION ALL SELECT 21
                       UNION ALL SELECT 22 UNION ALL SELECT 23 UNION ALL SELECT 24
        ) seq
   JOIN times t ON seq.seq >= t.time_from 
               AND seq.seq <  t.time_to
 ) a
SELECT COUNT(DISTINCT seq) hours
FROM (
SELECT seq.seq
  FROM seq_1_to_24 seq
   JOIN times t ON seq.seq >= t.time_from 
               AND seq.seq <  t.time_to
 ) a
# Without touching the `id` column, I create a sequential column `my_id`, assuming that the name of the  table is `times`:

alter table times add my_id int(3) not null after id;
SET @count = 0;
UPDATE times SET my_id = @count:= @count + 1;

# I use a temporary table `times2` that starts with the second row of the `times_from` column; Here, 9999 can be any large enough number:

create temporary table times2 as select my_id, time_from from times limit 1, 9999;

# Now I add a new column `time_end` to the original table. I update it with data from `time_from` column but 'shifted' by one row upwards:

alter table times add time_end int(2) not null;
update times a join times2 b on a.my_id = (b.my_id - 1) set a.time_end = b.time_from;

# Ensure that the value of `time_end` in the last row is not zero:

update times set time_end = time_to order by my_id desc limit 1;

# The required value is taken by using the minimum of columns `time_from` and `time_end`:

select sum(LEAST(time_to,time_end) - time_from) from times;

# Uncomment below to clean up just after getting the results:
    # alter table times drop column my_id;
    # alter table times drop column time_end;