Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >逐小时将超过一小时的持续时间插入另一个表

逐小时将超过一小时的持续时间插入另一个表
EN

Stack Overflow用户
提问于 2017-07-31 08:37:05
回答 1查看 32关注 0票数 1

请耐心点,我的英语不太好。

我已经设置了一个mysql表来将日志聚合到其中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create table logs(
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
player_id MEDIUMINT UNSIGNED NOT NULL,
`in` DATETIME NOT NULL,
`out` DATETIME NOT NULL,
channel_id INT UNSIGNED NOT NULL,
frame_id INT UNSIGNED NOT NULL,
media_id INT UNSIGNED NOT NULL
PRIMARY KEY (id)

我在inout之间使用timediff来找出文件播放了多长时间以及何时开始播放。它变得有点大了,所以我决定将需要的信息聚合到新的表中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create table reports(
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
year SMALLINT UNSIGNED NOT NULL,
month TINYINT UNSIGNED NOT NULL,
day TINYINT UNSIGNED NOT NULL,
hour TINYINT UNSIGNED NOT NULL,
player_id MEDIUMINT UNSIGNED NOT NULL,
channel_id INT UNSIGNED NOT NULL,
frame_id INT UNSIGNED NOT NULL,
media_id INT UNSIGNED NOT NULL,
count MEDIUMINT UNSIGNED NOT NULL,
duration MEDIUMINT UNSIGNED NOT NULL

我使用以下查询来填充reports表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
insert into reports (year, month, day, hour, player_id, media_id, channel_id, frame_id, count, duration)
select year(logs.in), month(logs.in) as Month, day(logs.in) as Day, hour(logs.in) as Hour, logs.player_id, logs.media_id, logs.channel_id, logs.frame_id, count(logs.media_id) as Count, SUM(TIME_TO_SEC(TIMEDIFF(logs.out, logs.in))) as Duration 
FROM logs
where (logs.player_id=1 OR logs.player_id=2)
GROUP BY year(logs.in), month(logs.in), day(logs.in), hour(logs.in), player_id, media_id, channel_id, frame_id;

如果timediff小于一个小时,则可以正常工作。但一种媒体可以播放的时间远远超过几分钟:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+-------+------+------+-----------+------------+----------+----------+----------------------+--------------+
| Month | Day  | Hour | player_id | channel_id | frame_id | media_id | count(logs.media_id) | Duration     |
+-------+------+------+-----------+------------+----------+----------+----------------------+--------------+
|     6 |   19 |   14 |         5 |          4 |       18 |       54 |                    1 | 275h 48m 24s |
|     6 |   20 |    8 |         4 |          3 |       18 |       54 |                    1 | 78h 45m 28s  |

因此,如果我检查该文件是否在6月20日的player_id 5上播放,我的查询将显示它不是,尽管它是。我想要实现的是填充我的报告表,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+-------+------+------+-----------+------------+----------+----------+----------------------+--------------+
| Month | Day  | Hour | player_id | channel_id | frame_id | media_id | count(logs.media_id) | Duration     |
+-------+------+------+-----------+------------+----------+----------+----------------------+--------------+
|     6 |   19 |   14 |         5 |          4 |       18 |       54 |                    1 |      48m 24s |
|     6 |   19 |   15 |         5 |          4 |       18 |       54 |                    1 |  1h  00m 00s |
|     6 |   19 |   16 |         5 |          4 |       18 |       54 |                    1 |  1h  00m 00s |

有什么办法吗?提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-01 15:53:14

好了,我找到了一个解决方案。首先,我必须创建一个带有时间范围的表。为了方便起见,我使用存储过程。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE DEFINER=`root`@`localhost` PROCEDURE `make_intervals`(startdate 
timestamp, enddate timestamp, intval integer, unitval varchar(10))
BEGIN
   declare thisDate timestamp;
   declare nextDate timestamp;
   set thisDate = startdate;
   drop temporary table if exists time_intervals;
   create temporary table if not exists time_intervals
  (
  interval_start timestamp,
  interval_end timestamp
  );
   repeat
      select
         case unitval
            when 'MICROSECOND' then timestampadd
 (MICROSECOND, intval, thisDate)
            when 'SECOND'      then timestampadd(SECOND, intval, thisDate)
            when 'MINUTE'      then timestampadd(MINUTE, intval, thisDate)
            when 'HOUR'        then timestampadd(HOUR, intval, thisDate)
            when 'DAY'         then timestampadd(DAY, intval, thisDate)
            when 'WEEK'        then timestampadd(WEEK, intval, thisDate)
            when 'MONTH'       then timestampadd(MONTH, intval, thisDate)
            when 'QUARTER'     then timestampadd(QUARTER, intval, thisDate)
            when 'YEAR'        then timestampadd(YEAR, intval, thisDate)
         end into nextDate;
  insert into time_intervals select thisDate, timestampadd(MICROSECOND, -1, nextDate);
  set thisDate = nextDate;
   until thisDate >= enddate
   end repeat;

 END 

然后,我根据这个临时表处理我的主表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT DATE(time_intervals.interval_start) AS Date, EXTRACT(HOUR FROM time_intervals.interval_start) AS Hour, player_id, channel_id, frame_id, media_id, count(media_id),
      sum(CASE 
          WHEN time_intervals.interval_start > TIMESTAMPADD(HOUR,HOUR(logs.in), DATE(logs.in)) 
    AND time_intervals.interval_start < TIMESTAMPADD(HOUR,HOUR(logs.out), DATE(logs.out))
    THEN 3600
WHEN time_intervals.interval_start = TIMESTAMPADD(HOUR,HOUR(logs.in), DATE(logs.in)) 
AND time_intervals.interval_start < TIMESTAMPADD(HOUR,HOUR(logs.out), DATE(logs.out))
THEN 3600 - EXTRACT(MINUTE FROM logs.in)*60 - EXTRACT(SECOND FROM logs.in)
 WHEN time_intervals.interval_start = TIMESTAMPADD(HOUR,HOUR(logs.out), DATE(logs.out))
AND time_intervals.interval_start > TIMESTAMPADD(HOUR,HOUR(logs.in), DATE(logs.in)) 
THEN EXTRACT(SECOND FROM logs.out) + EXTRACT(MINUTE FROM logs.out)*60 
WHEN time_intervals.interval_start = TIMESTAMPADD(HOUR,HOUR(logs.in), DATE(logs.in)) 
AND time_intervals.interval_start = TIMESTAMPADD(HOUR,HOUR(logs.out), DATE(logs.out))
THEN EXTRACT(MINUTE FROM logs.out)*60 + EXTRACT(SECOND FROM logs.out) - EXTRACT(MINUTE FROM logs.in)*60 - EXTRACT(SECOND FROM logs.in)
 ELSE 0
 END) AS duration 
FROM time_intervals
LEFT JOIN logs 
Force index(media_id, player_id, channel_id, frame_id)
  ON time_intervals.interval_start >= TIMESTAMPADD(HOUR,HOUR(logs.in), DATE(logs.in)) 
    AND time_intervals.interval_start <= TIMESTAMPADD(HOUR,HOUR(logs.out), DATE(logs.out))
    GROUP BY media_id, player_id, date, hour, channel_id, frame_id;

处理起来需要一段时间,特别是数十亿行的时候,就像我的例子一样,但是可以工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45410993

复制
相关文章
JavaScript删除列表中指定元素,过滤指定元素
作为工具人的我,昨晚有人问我用js怎么删除一个列表中等于0的元素 一开始我想的是用循环,后来百度发现有个东西叫做filter <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>删除0</title> </head> <body> <div
SingYi
2022/07/14
1.6K0
JavaScript删除列表中指定元素,过滤指定元素
JavaScript 函数定义的几种不同方式
在这篇中我们主要将函数的概念和函数声明的几种方式,牵扯到的还有函数中的形参和实参传参的问题,除此之外我们还会说一说 最常用 return 的作用,以及函数中处理参数的 arguments 等。
程序狗
2021/12/07
7680
JavaScript 函数定义的几种不同方式
JavaScript之函数(二) 函数内部三个不常见的属性
arguments就不多说了,但是arguments有一个callee属性,是一个指向arguments对象所在函数的指针。
赤蓝紫
2023/03/11
5480
vue列表过滤
一种常见的列表过滤方式是使用计算属性。计算属性是Vue.js提供的一种便捷的属性,它根据已有的数据计算出一个新的属性,并将结果缓存起来,只在相关依赖发生改变时才重新计算。通过使用计算属性,可以根据特定的条件过滤列表数据。
堕落飞鸟
2023/05/21
5910
python 列表过滤
-------or values = ['1', '2', '-3', '-', '4', 'N/A', '5'] def is_int(val): try: x = int(val) return True except ValueError: return False ivals = list(filter(is_int, values)) print(ivals)
用户5760343
2019/09/25
9440
python列表过滤的方法
在python中,对列表这样的数据结构进行过滤,提取自己需要的元素,组成新的列表,是很常见的操作,这就要自然而然的用到列表过滤了,而常用的过滤当然就是循环后通过if进行,但是这样子,显然就是代码的开支有些大。
py3study
2020/01/13
1.7K0
lodash源码阅读-----用于过滤的方法pull
lodash还有一个pullAll方法,用法几乎都是一样的,不同的只是它接收两个参数,第一个是目标数组,第二参数也是一个需要除去元素构成的数组。
Jou
2022/08/10
6230
JavaScript中的过滤器(filter)
filter()方法会创建一个新数组,原数组的每个元素传入回调函数中,回调函数中有return返回值,若返回值为true,这个元素保存到新数组中;若返回值为false,则该元素不保存到新数组中;原数组不发生改变。
刘亦枫
2020/03/19
3.4K0
Python:过滤序列的filter()函数
文章背景: 最近在学习廖雪峰老师的Python文章,其中有个章节讲到的是filter()函数,该函数用于过滤序列。在学习过程中,也顺带巩固了其它的知识点,在此进行相应的整理。
Exploring
2022/09/20
9590
python中的过滤函数 filter()
new_list = list(filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8]))
用户7886150
2021/01/24
9520
用于查找子列表总和的 Python 程序
以下程序返回子列表的总和,即使用 for 循环返回给定开始和结束索引的元素总和 −
很酷的站长
2023/02/23
1.8K0
用于查找子列表总和的 Python 程序
Python 列表的copy函数
列表的copy函数 功能 将当前列表复制一份相同的列表,新列表与旧列表内容相同,但内存空间不同 用法 list.copy() -> 该函数无参数 , 返回一个一模一样的列表 copy与二次赋值的区别 二次赋值的变量与原始变量享有相同内存空间 copy函数创建的新列表与原始列表不是一个内存空间,不同享数据变更 copy 属于 浅拷贝 a = [1,2,3] b = a a = [1,2,3] b = a.copy() b.append(4) b -> [1,2,3,4] a -> [1,2,3] 浅
Zkeq
2022/05/18
1K0
Python 列表的copy函数
PHP常见函数和过滤函数的深入探究
32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64 位系统上,最大带符号的 integer 值是 9223372036854775807。
V站CEO-西顾
2018/06/25
2.9K3
Python 列表的reverse函数
列表的reverse函数 功能 对当前的列表顺序进行反转 用法 list.reverse() 参数 无参数传递 代码 # coding:utf-8 students = [ {'name': 'dewei', 'age': 33, 'top': 174}, {'name': '小慕', 'age': 10, 'top': 175}, {'name': '小高', 'age': 18, 'top': 188}, {'name': 'Xiaoyun', 'age': 18, '
Zkeq
2022/05/18
5920
Python 列表的remove函数
列表的remove函数 功能 删除列表中的某个元素 用法 list.remove(item) 参数 item : 准备删除的函数 注意事项 如果删除的成员(元素)不存在 , 会直接报错 如果被删除的元素有多个 , 只会删除第一个(从左往右数) remove函数**不会返回一个新的列表,**而是在原先的列表中对元素进行删除(列表是可以被修改的) Python内置函数 del del把变量完全删除 代码 # coding:utf-8 shops = ['可乐', '洗发水', '可乐', '牛奶', '牛奶'
Zkeq
2022/05/18
6770
Python 列表的clear函数
列表的clear函数 功能 将当前列表中的数据清空 用法 list.clear() -> 该函数无参数 , 无返回值 注意 比空列表节省性能 代码 # coding:utf-8 mix = ['python', 1, (1,), {'name': 'dewei'}] print(mix, len(mix)) mix.clear() print(mix, len(mix)) mixs = []
Zkeq
2022/05/18
8690
Python 列表的extend函数
列表的extend函数 功能 将其他列表或元组中的元素导入当前列表中 用法 list.extend(iterable) 参数 iterable代表列表或元组 , 该函数无返回值 注意事项 传入的必须是iterable 直接传入字符串的话会被拆分成很多个单个字符 不可传入整形或者布尔类型之类的(不是iterable就不行) 传入字典的话只会保留key的值 代码 # coding:utf-8 manhua = [] history = [] code = [] new_manhua = ('a', 'b',
Zkeq
2022/05/18
7470
用于列表下拉加载loading动画
一、效果图 弹跳加载 二、实现代码 <view class="bouncing-loader"> <view></view> <view></view> <view></view> </v
_kyle
2020/08/24
3.6K0
用于列表下拉加载loading动画
python 列表函数
注意:(1)list1[beg:end]将显示列表的从list1[beg]到list1[end-1]的元素,list1[end]不会显示
全栈程序员站长
2022/09/08
5420
python 列表函数
点击加载更多

相似问题

用于创建第三个列表的2个不同长度的列表

30

用于将值追加到三个列表的小函数

20

用于过滤输入列表的Scala多态函数

20

Javascript函数,用于查找数字列表的模式

20

JavaScript -创建用于编辑列表项的函数

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文