我正在尝试计算单位不是100%的持续时间。
|ID| DATE | UNITNAME | PERCENTAGE|
------------------------------------------------
|1 |2018-01-20 00:00:00 | UNIT1 |100 |
|2 |2018-01-20 00:05:00 | UNIT1 |0 |
|3 |2018-01-20 00:10:00 | UNIT1 |100 |
|4 |2018-01-20 00:15:00 | UNIT1 |99 |
|5 |2018-01-20 00:20:00 | UNIT1 |50 |
|6 |2018-01-20 00:25:00 | UNIT1 |100 |
所以在这里,我希望输出类似于:
| UNITNAME | RPO |
| UNIT1 | 00:15:00 |
单位在00:05:00报告为0%,然后在00:10:00报告的下一个间隔为100%。因此,我将假设该装置已经退出RPO 5分钟。这种情况会在00:15:00再次发生,直到00:25:00,因此假设整个期间都出现了这种情况。
我看起来很沮丧,并且在SQL Fiddle创建了关注 使用以下内容;
select UNITNAME, SEC_TO_TIME(SUM(TIME_TO_SEC(duration))) as 'RPO'
from(
SELECT UNITNAME, TIMEDIFF(MAX(DATE), MIN(DATE)) AS duration, MIN(DATE) AS
startime, MAX(DATE) AS endtime
FROM (
SELECT
tp.*
, @val_change := IF(@prev_val != Percentage, @val_change+1 , @val_change) AS vc
, @prev_val := Percentage
FROM
Replication_History tp
, (SELECT @prev_val := NULL, @val_change := 0) var_init_subquery
ORDER BY UNITNAME, DATE
) sq
WHERE Percentage =100
GROUP BY UNITNAME, vc
)ts
group by UNITNAME
这种作品,但没有正确管理100%之间的差距。
任何人做过类似的事情吗?
答案 0 :(得分:2)
它只是这些值之间差异的总和......
SELECT a.unitname
, MIN(a.date) my_start
, a.min_date my_end
FROM
( SELECT x.*
, MIN(y.date) min_date
FROM replication_history x
LEFT
JOIN replication_history y
ON y.unitname = x.unitname
AND y.date > x.date
AND y.percentage = 100
WHERE x.percentage < 100
GROUP
BY x.id
) a
GROUP
BY unitname
, my_end;
+----------+---------------------+---------------------+
| unitname | my_start | my_end |
+----------+---------------------+---------------------+
| UNIT1 | 2018-01-20 10:15:00 | 2018-01-20 10:25:00 |
| UNIT2 | 2018-01-20 10:05:00 | 2018-01-20 10:10:00 |
| UNIT2 | 2018-01-20 10:15:00 | 2018-01-20 10:25:00 |
+----------+---------------------+---------------------+
答案 1 :(得分:1)
你可以使用&#39; Gaps-and-islands&#39;来解决这个问题。的方法:
SELECT UNITNAME, SEC_TO_TIME(SUM(TIME_TO_SEC(duration))) AS PRO
FROM (
SELECT UNITNAME, TIMEDIFF(MAX(DATE), MIN(DATE)) AS duration
FROM (
SELECT ID, DATE, UNITNAME, Percentage,
@rn := IF(@unit = UNITNAME, IF(Percentage = 100, @rn + 1, @rn),
IF(@unit := UNITNAME, 1, 1)) AS grp
FROM replication_history
CROSS JOIN (SELECT @unit := '', @rn := 0) AS v
ORDER BY UNITNAME, DATE DESC) AS t
GROUP BY UNITNAME, grp
HAVING COUNT(CASE WHEN Percentage <> 100 THEN 1 END) > 0) AS u
GROUP BY UNITNAME
要了解此查询的工作原理,您必须执行最里面的子查询并检查它产生的结果。
所以,这个查询:
SELECT ID, DATE, UNITNAME, Percentage, grp
FROM (
SELECT ID, DATE, UNITNAME, Percentage,
@rn := IF(@unit = UNITNAME, IF(Percentage = 100, @rn + 1, @rn),
IF(@unit := UNITNAME, 1, 1)) AS grp
FROM replication_history
CROSS JOIN (SELECT @unit := '', @rn := 0) AS v
ORDER BY UNITNAME, DATE DESC) AS t
ORDER BY UNITNAME, DATE
产生以下输出:
ID, DATE, UNITNAME, Percentage, grp
-------------------------------------------------------
204200, 2018-01-20 10:00:00, UNIT1, 100, 3
204201, 2018-01-20 10:05:00, UNIT1, 0, 2
204202, 2018-01-20 10:10:00, UNIT1, 100, 2
204203, 2018-01-20 10:15:00, UNIT1, 99, 1
204204, 2018-01-20 10:20:00, UNIT1, 50, 1
204205, 2018-01-20 10:25:00, UNIT1, 100, 1
因此,正如您可以看到的上述数据,grp
字段标识了PRO&#39;间隔。仅具有100
百分比值的组将被第二级子查询过滤掉。