ねら~ITエンジニア雑記

やきうのお兄ちゃんが綴るOracle Databaseメインのブログ

Oracle Database の PIVOT文で取得レコードの縦横を変換する。

PIVOT文で取得レコードの縦持ち/横持ちを変換するやで彡(゚)(゚)
このSQLで取得できる……

COLUMN TARGET_NAME FORMAT A8;
COLUMN TARGET_TYPE FORMAT A15;
  SELECT TARGET_NAME
       , TARGET_TYPE
       , AVAILABILITY_STATUS                            AS AVAILABILITY_STATUS
       , ROUND(SUM(END_TIMESTAMP - START_TIMESTAMP), 2) AS DAYS
    FROM MGMT$AVAILABILITY_HISTORY
   WHERE TARGET_TYPE IN ('oracle_database', 'rac_database')
     AND TARGET_NAME IN ('REPO', 'orclk')
     AND START_TIMESTAMP >= (SYSTIMESTAMP-365)
   GROUP BY TARGET_NAME, TARGET_TYPE, AVAILABILITY_STATUS
   ORDER BY TARGET_NAME, TARGET_TYPE, AVAILABILITY_STATUS;

TARGET_N TARGET_TYPE     AVAILABILITY_ST       DAYS
-------- --------------- --------------- ----------
REPO     oracle_database Agent Down            2.67
REPO     oracle_database Blackout               .01
REPO     oracle_database Pending/Unknown          0
REPO     oracle_database Target Down            .24
REPO     oracle_database Target Up           345.32
REPO     oracle_database Unreachable               
orclk    rac_database    Metric Error             0
orclk    rac_database    Pending/Unknown      34.34
orclk    rac_database    Target Down           6.45
orclk    rac_database    Target Up           222.98
orclk    rac_database    Unreachable               

11行選択されました

この結果を…

↓のようにしたい。

PIVOT文を使うやで彡(゚)(゚) サンプルは下記

COLUMN TARGET_NAME FORMAT A8;
COLUMN TARGET_TYPE FORMAT A15;
COLUMN AgentDown FORMAT 999.99;
COLUMN Blackout FORMAT 999.99;
COLUMN Pending_Unknown FORMAT 999.99;
COLUMN TargetDown FORMAT 999.99;
COLUMN TargetUp FORMAT 999.99;
COLUMN MetricError FORMAT 999.99;
COLUMN Unreachable FORMAT 999.99;
SELECT * FROM (
  SELECT TARGET_NAME
       , TARGET_TYPE
       , AVAILABILITY_STATUS                            AS AVAILABILITY_STATUS
       , ROUND(SUM(END_TIMESTAMP - START_TIMESTAMP), 2) AS DAYS
    FROM MGMT$AVAILABILITY_HISTORY
   WHERE TARGET_TYPE IN ('oracle_database', 'rac_database')
     AND TARGET_NAME IN ('REPO', 'orclk')
     AND START_TIMESTAMP >= (SYSTIMESTAMP-365)
   GROUP BY TARGET_NAME, TARGET_TYPE, AVAILABILITY_STATUS
)
PIVOT (
  MAX(DAYS) FOR AVAILABILITY_STATUS IN (
      'Agent Down'      AS AgentDown
    , 'Blackout'        AS Blackout
    , 'Pending/Unknown' AS Pending_Unknown
    , 'Target Down'     AS TargetDown
    , 'Target Up'       AS TargetUp
    , 'Metric Error'    AS MetricError
    , 'Unreachable'     AS Unreachable
  )
)
ORDER BY TARGET_TYPE, TARGET_NAME;

TARGET_N TARGET_TYPE     AGENTDOWN BLACKOUT PENDING_UNKNOWN TARGETDOWN TARGETUP METRICERROR UNREACHABLE
-------- --------------- --------- -------- --------------- ---------- -------- ----------- -----------
REPO     oracle_database      2.67      .01             .00        .24   345.32                        
orclk    rac_database                                 34.34       6.45   222.98         .00            

上手くいってるやね彡(^)(^) ポイントは……

  • PIVOT文の最初の「(」の直後は集約関数(MIN, MAX, SUM等) ※この例ではMAXを指定
  • 列名にしたい列値を持っているカラムを FOR の後に指定 ※この例では AVAILABILITY_STATUS列を指定
  • IN には 列値⇒列名 に 変換したいリテラル文字を指定 ※列値には何が返ってくるか、予め知っておく必要がある。あるいはSQLで自分で制御する。

てなとこやろうか。マニュアルは下記やで彡(゚)(゚)

Oracle Database SQL言語リファレンス
12cリリース1 (12.1) B71278-10
SELECT
pivot_clause
http://docs.oracle.com/cd/E57425_01/121/SQLRF/statements_10002.htm#CHDCEJJE
PIVOTおよびUNPIVOTの使用例
http://docs.oracle.com/cd/E57425_01/121/SQLRF/statements_10002.htm#CHDFIIDD

下記の記事も参考にしています。いつも参考にさせて頂いております(`・ω・)ゞ

図でイメージするOracle DatabaseのSQL全集
第8回 PivotとUnPivot
OracleのSQLの各機能をイメージを交えて解説
http://www.oracle.com/technetwork/jp/articles/otnj-sql-image8-1869298-ja.html

Qiitaにも書いたやで彡(^)(^)

Oracle Database の PIVOT文で取得レコードの縦横を変換する。
http://qiita.com/ora_gonsuke777/items/558a6ae91b7490b7bea1