Your question has two parts, and both should be handled in two different requests. Because the output is based on two different sets of strings.
Customization
SQL> CREATE TABLE t AS SELECT * FROM(WITH DATA(dt, status) AS( 2 SELECT to_date('07-Jul-15 12:05:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 3 SELECT to_date('07-Jul-15 12:10:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 4 SELECT to_date('07-Jul-15 12:15:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 5 SELECT to_date('07-Jul-15 12:20:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 0 FROM dual UNION ALL 6 SELECT to_date('07-Jul-15 12:25:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 0 FROM dual UNION ALL 7 SELECT to_date('07-Jul-15 12:30:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 0 FROM dual UNION ALL 8 SELECT to_date('07-Jul-15 12:35:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 9 SELECT to_date('07-Jul-15 12:40:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 10 SELECT to_date('07-Jul-15 12:45:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 11 SELECT to_date('07-Jul-15 12:50:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 12 SELECT to_date('07-Jul-15 12:55:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 0 FROM dual UNION ALL 13 SELECT to_date('07-Jul-15 13:00:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 0 FROM dual UNION ALL 14 SELECT to_date('07-Jul-15 13:05:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 15 SELECT to_date('07-Jul-15 13:10:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 16 SELECT to_date('07-Jul-15 13:15:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 1 FROM dual UNION ALL 17 SELECT to_date('07-Jul-15 13:20:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 0 FROM dual UNION ALL 18 SELECT to_date('07-Jul-15 13:25:00', 'dd-Mon-rr hh24:mi:ss', 'NLS_DATE_LANGUAGE=AMERICAN'), 0 FROM dual 19 ) SELECT * FROM DATA); Table created.
Table data
SQL> SELECT * FROM t; DT STATUS ------------------ ---------- 07-Jul-15 12:05:00 1 07-Jul-15 12:10:00 1 07-Jul-15 12:15:00 1 07-Jul-15 12:20:00 0 07-Jul-15 12:25:00 0 07-Jul-15 12:30:00 0 07-Jul-15 12:35:00 1 07-Jul-15 12:40:00 1 07-Jul-15 12:45:00 1 07-Jul-15 12:50:00 1 07-Jul-15 12:55:00 0 07-Jul-15 13:00:00 0 07-Jul-15 13:05:00 1 07-Jul-15 13:10:00 1 07-Jul-15 13:15:00 1 07-Jul-15 13:20:00 0 07-Jul-15 13:25:00 0 17 rows selected.
- Number of outputs: the number of shutdowns in this case is 3 based on 0, and 1 is turned off.
You need to use the analytic function LAG () .
SQL> SELECT TO_CHAR(dt, 'dd-Mon-rr hh24:mi:ss') dt, 2 status 3 FROM 4 (SELECT t.*, 5 CASE 6 WHEN lag(status) OVER(ORDER BY dt) <> status 7 THEN 1 8 ELSE 0 9 END chg 10 FROM t 11 ) 12 WHERE status = 0 13 AND chg =1; DT STATUS ------------------ ---------- 07-Jul-15 12:20:00 0 07-Jul-15 12:55:00 0 07-Jul-15 13:20:00 0
So, the output has 3 lines, which means 3 times the shutdown event. To get an account, you just need to use the COUNT function.
- The period between each shutdown
Example:
- From: 07-Jul-15 12:05:00 To: 07-Jul-15 12:15:00 Duration: 15 minutes
- From: 07-Jul-15 12:35:00 To: 07-Jul-15 12:50:00 Duration: 20 minutes
Once again you need to use the analytic function LAG () . The difference between dates returns the number of days . To convert it to minutes, multiply it by 24 * 60 .
SQL> SELECT * FROM( 2 SELECT t.*, 3 CASE 4 WHEN lag(status) OVER(ORDER BY dt) <> status 5 THEN 1 6 ELSE 0 7 END chg, 8 24*60*(dt - lag(dt) over(order by dt)) gap 9 FROM t 10 ) t 11 WHERE status =1 and chg =0; DT STATUS CHG GAP ------------------ ---------- ---------- ---------- 07-Jul-15 12:05:00 1 0 07-Jul-15 12:10:00 1 0 5 07-Jul-15 12:15:00 1 0 5 07-Jul-15 12:40:00 1 0 5 07-Jul-15 12:45:00 1 0 5 07-Jul-15 12:50:00 1 0 5 07-Jul-15 13:10:00 1 0 5 07-Jul-15 13:15:00 1 0 5 8 rows selected. SQL>
So, based on the above query, to find the total time when the system was ready, use SUM .
SQL> SELECT SUM(gap) on_minutes FROM( 2 SELECT t.*, 3 CASE 4 WHEN lag(status) OVER(ORDER BY dt) <> status 5 THEN 1 6 ELSE 0 7 END chg, 8 24*60*(dt - lag(dt) over(order by dt)) gap 9 FROM t 10 ) t 11 WHERE status =1 and chg =0; ON_MINUTES ---------- 35 SQL>
So, the system went up by 35 minutes .