table-1
+-----+----------+--------+----------+---------------------+
| id | isp_name | uptime | downtime | stamp_date |
+-----+----------+--------+----------+---------------------+
| 581 | AIRCEL | 0 | 289 | 2015-01-23 10:27:26 |
| 584 | AIRCEL | 310 | 0 | 2015-01-23 10:32:27 |
| 587 | AIRCEL | 0 | 297 | 2015-01-23 10:37:28 |
| 590 | AIRCEL | 0 | 303 | 2015-01-23 10:42:29 |
| 593 | AIRCEL | 0 | 311 | 2015-01-23 10:47:30 |
| 596 | AIRCEL | 272 | 0 | 2015-01-23 10:52:31 |
| 599 | AIRCEL | 300 | 0 | 2015-01-23 10:57:32 |
| 602 | AIRCEL | 0 | 317 | 2015-01-23 11:02:33 |
| 605 | AIRCEL | 0 | 287 | 2015-01-23 11:07:34 |
| 608 | AIRCEL | 317 | 0 | 2015-01-23 11:12:35 |
| 611 | AIRCEL | 292 | 0 | 2015-01-23 11:17:36 |
| 614 | AIRCEL | 0 | 292 | 2015-01-23 11:22:37 |
+-----+----------+--------+----------+---------------------+
以上是我的正常运行时间和停机时间结果。
我想仅显示连续的停机时间记录,如下表所示。
table-2
+----------+--------+----------+---------------------+---------------------+
| isp_name | uptime | downtime | start_time | end_time |
+----------+--------+----------+---------------------+---------------------+
| AIRCEL | 0 | 289 | 2015-01-23 10:27:26 | 2015-01-23 10:32:28 |
| AIRCEL | 0 | 297 | 2015-01-23 10:37:28 | 2015-01-23 10:52:31 |
| AIRCEL | 0 | 317 | 2015-01-23 11:02:33 | 2015-01-23 11:12:35 |
| AIRCEL | 0 | 292 | 2015-01-23 11:22:37 | NOW |
+----------+-------+----------+---------------------+---------------------+
SELECT isp_name,
interface_up_time AS uptime,
interface_down_time AS downtime,
min(stamp_date) AS start_time,
max(stamp_date) AS end_time
FROM
(SELECT r.*,
(@ups := @ups + (interface_up_time = 0)) AS ups,
(@downs := @downs + (interface_up_time != 0)) AS downs
FROM interface_stats r
CROSS JOIN
(SELECT @ups := 0, @downs := 0) vars
WHERE isp_name='AIRCEL'
AND device_id='fmpvd2001100999'
AND stamp_date >='2015-01-23 10:23:10'
AND stamp_date <='2015-01-23 11:23:10'
ORDER BY stamp_date) r
GROUP BY interface_up_time, (CASE
WHEN interface_up_time = 0 THEN downs
ELSE ups
END);
我已经尝试了上面的查询并获得了像
这样的结果table-3
+----------+--------+----------+---------------------+---------------------+
| isp_name | uptime | downtime | start_time | end_time |
+----------+--------+----------+---------------------+---------------------+
| AIRCEL | 0 | 289 | 2015-01-23 10:27:26 | 2015-01-23 10:27:26 |
| AIRCEL | 0 | 297 | 2015-01-23 10:37:28 | 2015-01-23 10:47:30 |
| AIRCEL | 0 | 317 | 2015-01-23 11:02:33 | 2015-01-23 11:07:34 |
| AIRCEL | 0 | 292 | 2015-01-23 11:22:37 | 2015-01-23 11:22:37 |
| AIRCEL | 272 | 0 | 2015-01-23 10:52:31 | 2015-01-23 10:52:31 |
| AIRCEL | 292 | 0 | 2015-01-23 11:17:36 | 2015-01-23 11:17:36 |
| AIRCEL | 300 | 0 | 2015-01-23 10:57:32 | 2015-01-23 10:57:32 |
| AIRCEL | 310 | 0 | 2015-01-23 10:32:27 | 2015-01-23 10:32:27 |
| AIRCEL | 317 | 0 | 2015-01-23 11:12:35 | 2015-01-23 11:12:35 |
+----------+--------+----------+---------------------+---------------------+
你能帮助我取得成果吗?
答案 0 :(得分:0)
这是一种方式。这得到了所有结果。如果您只想要停机时间,请相应地修改最终的WHERE子句。
SELECT a.isp_name
, a.status
, a.duration
, a.stamp_date start
, MIN(c.stamp_date) end
FROM
( SELECT isp_name
, CASE WHEN uptime > 0 THEN 'up' ELSE 'down' END status
, CASE WHEN uptime > 0 THEN uptime ELSE downtime END duration
, stamp_date
, @a := @a + 1 seq
FROM my_table
JOIN (SELECT @a:=0) vars
) a
LEFT
JOIN
( SELECT isp_name
, CASE WHEN uptime > 0 THEN 'up' ELSE 'down' END status
, CASE WHEN uptime > 0 THEN uptime ELSE downtime END duration
, stamp_date
, @b := @b + 1 seq
FROM my_table
JOIN (SELECT @b:=0) vars
) b
ON b.seq = a.seq - 1
AND b.isp_name = a.isp_name
AND b.status = a.status
LEFT
JOIN
( SELECT isp_name
, CASE WHEN uptime > 0 THEN 'up' ELSE 'down' END status
, CASE WHEN uptime > 0 THEN uptime ELSE downtime END duration
, stamp_date
, @c := @c + 1 seq
FROM my_table
JOIN (SELECT @c:=0) vars
) c
ON c.seq >= a.seq
AND c.isp_name = a.isp_name
AND c.status = a.status
LEFT
JOIN
( SELECT isp_name
, CASE WHEN uptime > 0 THEN 'up' ELSE 'down' END status
, CASE WHEN uptime > 0 THEN uptime ELSE downtime END duration
, stamp_date
, @d := @d + 1 seq
FROM my_table
JOIN (SELECT @d:=0) vars
) d
ON d.seq = c.seq + 1
AND d.isp_name = a.isp_name
AND d.status = a.status
WHERE b.seq IS NULL
AND c.seq IS NOT NULL
AND d.seq IS NULL
GROUP
BY a.seq;
答案 1 :(得分:-1)
我认为这可能是您正在寻找的内容,虽然我只在SQL Server中进行了测试,因为我没有使用MySQL,但应该使用相同的...
SELECT MIN(isp_name) AS isp_name,
MIN(uptime) AS uptime,
MIN(downtime) AS downtime,
MIN(start_time) AS start_time,
end_time FROM
(SELECT d.isp_name,
d.uptime,
d.downtime,
d.stamp_date AS start_time,
COALESCE((SELECT MIN(CAST(u.stamp_date AS VARCHAR(20)))
FROM table-1 u
WHERE u.stamp_date > d.stamp_date
AND u.uptime > 0), 'NOW') AS end_time
FROM table-1 d
WHERE d.downtime > 0) down
GROUP BY end_time;
唯一的问题是将u.stamp_date转换为VARCHAR似乎将end_time
转换为&#34;人类可读&#34;格式,我必须做以显示&#34;现在&#34;而不是&#34; NULL&#34; - 我确定是否有方法可以在stackoverflow上找到它... OTOH你可能很高兴只显示&#34; NULL&#34; ....或者在MySQL你可能不需要施展它......
您可以使用ISNULL
代替COALESCE
,我认为它应该会得到相同的结果。