如何通过'id = 1'进行总和搜索并将其小时数加起来。 第一行将及时到达,下一行将是他们的外出时间。
下面应该加起来为5:43:29
id, ts
1,2016-06-20 04:25:32
3,2016-06-20 07:40:09
1,2016-06-20 09:37:46
3,2016-06-20 14:40:57
1,2016-06-20 15:12:14
1,2016-06-20 15:43:29
2,2016-06-20 15:47:01
2,2016-06-20 17:47:03
答案 0 :(得分:0)
哦,小伙子,这很有趣:
SELECT SEC_TO_TIME(
SUM(UNIX_TIMESTAMP(
(SELECT ts FROM example_table e2 WHERE id = ranked.id AND ts > ranked.ts ORDER BY id, ts LIMIT 1)
)-UNIX_TIMESTAMP(ts))
)
FROM (
SELECT
@row := @row +1 AS rownum, id, ts
FROM (
SELECT @row :=0) r, example_table
WHERE id = 1
ORDER BY id ASC, ts ASC
) ranked
WHERE ranked.rownum % 2 = 1
首先我们获取所有奇数行:1,3,5,7和soforth。接下来,我们使用子查询来获取与该行匹配的下一个时间戳(打卡时间),并获得差异(以秒为单位)。 Sum将总计秒数,sec_to_time会将其转换为友好的可读格式。
答案 1 :(得分:0)
您可以使用用户定义的变量添加行号。奇数行表示开始时间,当它是if(r%2=0,1,-1)
的开始时间时乘以-1,并将它们相加:
select sec_to_time(sum(time_to_sec(ts)*if(r%2=0,1,-1)))
from (
select @row:=@row+1 r, a.*
from Table1 a
join (select @row:=0) b
where a.id = 1) a;
答案 2 :(得分:0)
这里我的回答是一个样本
使用这样的SQL:
SELECT
t_from.id,
SEC_TO_TIME(SUM(TIME_TO_SEC( TIMEDIFF(
( SELECT ts
FROM t t_to
WHERE
t_to.ts > t_from.ts_from
AND
t_to.id = t_from.id
ORDER BY t_to.id,t_to.ts
LIMIT 1
)
, t_from.ts_from
)))) AS ts_diff
FROM (
SELECT @nr:=((@nr+1) %2) AS nr,t.id,t.ts AS ts_from
FROM t
CROSS JOIN ( SELECT @nr:=0) AS parameter
ORDER BY id
) AS t_from
WHERE nr =1
GROUP BY t_from.id;
我的表
MariaDB [yourSchema]> select * from t;
+----+---------------------+
| id | ts |
+----+---------------------+
| 1 | 2016-06-20 04:25:32 |
| 3 | 2016-06-20 07:40:09 |
| 1 | 2016-06-20 09:37:46 |
| 3 | 2016-06-20 14:40:57 |
| 1 | 2016-06-20 15:12:14 |
| 1 | 2016-06-20 15:43:29 |
| 2 | 2016-06-20 15:47:01 |
| 2 | 2016-06-20 17:47:03 |
+----+---------------------+
8 rows in set (0.00 sec)
转换为开始结束时间
MariaDB [yourSchema]> SELECT
-> t_from.id
-> , t_from.ts_from,
-> ( SELECT ts
-> FROM t t_to
-> WHERE
-> t_to.ts > t_from.ts_from
-> AND
-> t_to.id = t_from.id
-> ORDER BY t_to.id,t_to.ts
-> LIMIT 1
-> ) AS ts_to
-> FROM (
-> SELECT @nr:=((@nr+1) %2) AS nr,t.id,t.ts AS ts_from
-> FROM t
-> CROSS JOIN ( SELECT @nr:=0) AS parameter
-> ORDER BY id
-> ) AS t_from
-> WHERE nr =1;
+----+---------------------+---------------------+
| id | ts_from | ts_to |
+----+---------------------+---------------------+
| 1 | 2016-06-20 04:25:32 | 2016-06-20 09:37:46 |
| 1 | 2016-06-20 15:12:14 | 2016-06-20 15:43:29 |
| 2 | 2016-06-20 15:47:01 | 2016-06-20 17:47:03 |
| 3 | 2016-06-20 07:40:09 | 2016-06-20 14:40:57 |
+----+---------------------+---------------------+
4 rows in set (0.00 sec)
MariaDB [yourSchema]>
按ID分享差异和分组
MariaDB [yourSchema]> SELECT
-> t_from.id,
-> SEC_TO_TIME(SUM(TIME_TO_SEC( TIMEDIFF(
-> ( SELECT ts
-> FROM t t_to
-> WHERE
-> t_to.ts > t_from.ts_from
-> AND
-> t_to.id = t_from.id
-> ORDER BY t_to.id,t_to.ts
-> LIMIT 1
-> )
-> , t_from.ts_from
-> )))) AS ts_diff
-> FROM (
-> SELECT @nr:=((@nr+1) %2) AS nr,t.id,t.ts AS ts_from
-> FROM t
-> CROSS JOIN ( SELECT @nr:=0) AS parameter
-> ORDER BY id
-> ) AS t_from
-> WHERE nr =1
-> GROUP BY t_from.id;
+----+----------+
| id | ts_diff |
+----+----------+
| 1 | 05:43:29 |
| 2 | 02:00:02 |
| 3 | 07:00:48 |
+----+----------+
3 rows in set (0.00 sec)
MariaDB [yourSchema]>
答案 3 :(得分:0)
自己加入表并搜索下一个时间戳:
select t1.id,
t1.ts as ts_from,
min(t2.ts) as ts_to,
timediff(min(t2.ts), t1.ts) as uptime
from uptime t1
join uptime t2
on t2.id = t1.id
and t2.ts > t1.ts
where t1.id = 1
group by t1.id, t1.ts
结果:
| id | ts_from | ts_to | uptime |
|----|---------------------|---------------------|----------|
| 1 | 2016-06-20 04:25:32 | 2016-06-20 09:37:46 | 05:12:14 |
| 1 | 2016-06-20 09:37:46 | 2016-06-20 15:12:14 | 05:34:28 |
| 1 | 2016-06-20 15:12:14 | 2016-06-20 15:43:29 | 00:31:15 |
您需要id, ts
上的索引。
ALTER TABLE `uptime` ADD INDEX `id_ts` (`id`, `ts`);
<强>更新强>
在再次阅读你的问题后,我想我得到了你所追求的。您可以在子查询中使用obove查询,在偶数行和奇数行之间切换会话变量以及条件SUM:
select sec_to_time(sum(
case when @switch := 1 - @switch then time_to_sec(sub.uptime) end
)) as uptime
from (
select timediff(min(t2.ts), t1.ts) as uptime
from uptime t1
join uptime t2
on t2.id = t1.id
and t2.ts > t1.ts
where t1.id = 1
group by t1.id, t1.ts
order by t1.ts
) sub
join (select @switch := 0) init_switch