【问题标题】:Oracle downtime in minutes per month每月 Oracle 停机时间(以分钟为单位)
【发布时间】:2016-04-13 22:13:31
【问题描述】:

这是用 Oracle 11g 或 12c 编写的...

你好,

我试图将这些数据转化为过去 12 个月的停机时间,以这种方式形成以支持图表。

在下面的 Oracle SQL 查询中,注释查询“M”显示了如何每月放入一条记录。查询“M”显示了我需要的最终形状,除了我需要将停机时间放入每个月的 bin 中。

然而,数据是由查询“D”提供的,为了这个例子,我已经模拟了它。当然,更好的示例可能会显示更多边缘情况,例如跨越一个月的第一天等。但是这个示例就足够了。

WITH 
/*
  M AS (  
    SELECT ADD_MONTHS (TRUNC (SYSDATE, 'MONTH'), -1 * LEVEL) AS MO
    , 0 AS DOWNTIME FROM DUAL
     CONNECT BY LEVEL <= 12),
*/
D AS (  -- data simulating a downtime day
     SELECT 'Target Up' AS AVAILABILITY_STATUS,
            TO_DATE ('9/25/2015 15:12:47', 'MM/DD/YYYY HH24:MI:SS')
               AS SINCE,
            385392 AS MINUTES
       FROM DUAL
     UNION ALL
     SELECT 'Target Down' AS AVAILABILITY_STATUS,
            TO_DATE ('11/25/2015 15:12:00', 'MM/DD/YYYY HH24:MI:SS')
               AS SINCE,
            1440 AS MINUTES
       FROM DUAL
     UNION ALL
     SELECT 'Target Up' AS AVAILABILITY_STATUS,
            TO_DATE ('11/26/2015 15:12:00', 'MM/DD/YYYY HH24:MI:SS')
               AS SINCE,
            200122 AS MINUTES
       FROM DUAL)
SELECT *
FROM D
   PIVOT
      (SUM (MINUTES)
      AS TIME
      FOR AVAILABILITY_STATUS
      IN ('Target Up' AS UP,
         'Target Down' AS DOWN,
         'Blackout' AS BLACKOUT));

结果现在看起来像这样:

SINCE UP_TIME DOWN_TIME BLACKOUT_TIME 2015 年 9 月 25 日下午 3:12:47 385,392 2015 年 11 月 25 日下午 3:12:00 1,440 2015 年 11 月 26 日下午 3:12:00 200,122

但我需要它看起来像这样:

MO DOWN_MINUTES 2016 年 3 月 1 日 0 2016 年 2 月 1 日 0 2016 年 1 月 1 日 0 2015 年 12 月 1 日 0 2015 年 11 月 1 日 1440 2015 年 10 月 1 日 0 2015 年 9 月 1 日 0 2015 年 8 月 1 日 0 2015 年 7 月 1 日 0 2015 年 6 月 1 日 0 2015 年 5 月 1 日 0 2015 年 4 月 1 日 0

P.S.:为了小组的利益,查询“M”中的实际停机时间由以下查询生成,该查询从 Oracle Enterprise Manager 读取:

WITH X
 AS (SELECT START_TIMESTAMP,
            NVL (END_TIMESTAMP, SYSDATE) AS END_TIMESTAMP,
            AVAILABILITY_STATUS,
            TRUNC (
               (NVL (END_TIMESTAMP, SYSDATE) - START_TIMESTAMP) * 24 * 60)
               MINUTES
       FROM MGMT$AVAILABILITY_HISTORY
      WHERE     AVAILABILITY_STATUS IN
                   ('Target Down', 'Target Up', 'Blackout')
  )
  SELECT AVAILABILITY_STATUS,
     MIN (START_TIMESTAMP) AS SINCE,
     SUM (MINUTES) AS MINUTES
  FROM X
GROUP BY AVAILABILITY_STATUS
ORDER BY MIN (START_TIMESTAMP);

提前谢谢你。这几天我一直在旋转我的车轮,是时候寻求帮助了。

【问题讨论】:

    标签: sql oracle oracle11g oracle12c date-math


    【解决方案1】:

    试试这个:

    WITH 
    M AS (  
        SELECT ADD_MONTHS (TRUNC (SYSDATE, 'MONTH'), -1 * LEVEL) AS MO
        , 0 AS DOWNTIME FROM DUAL
        CONNECT BY LEVEL <= 12),
    
    D AS (  -- data simulating a downtime day
         SELECT 'Target Up' AS AVAILABILITY_STATUS,
                TO_DATE ('9/25/2015 15:12:47', 'MM/DD/YYYY HH24:MI:SS')
                   AS SINCE,
                385392 AS MINUTES
           FROM DUAL
         UNION ALL
         SELECT 'Target Down' AS AVAILABILITY_STATUS,
                TO_DATE ('11/25/2015 15:12:00', 'MM/DD/YYYY HH24:MI:SS')
                   AS SINCE,
                1440 AS MINUTES
           FROM DUAL
         UNION ALL
         SELECT 'Target Up' AS AVAILABILITY_STATUS,
                TO_DATE ('11/26/2015 15:12:00', 'MM/DD/YYYY HH24:MI:SS')
                   AS SINCE,
                200122 AS MINUTES
           FROM DUAL)
    SELECT M.mo, Nvl(s, 0) AS minutes
    FROM M
         LEFT JOIN (  SELECT TRUNC (SINCE, 'MONTH') AS D, SUM (MINUTES) AS S
                        FROM D
                       WHERE AVAILABILITY_STATUS = 'Target Down'
                    GROUP BY TRUNC (SINCE, 'MONTH')) GR
            ON GR.D = M.MO
    ORDER BY 1;
    

    【讨论】:

    • 完美!非常感谢你,亚当。巧妙的分组!
    猜你喜欢
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多