質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

Oracle Database 11g

Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

Q&A

解決済

1回答

17770閲覧

OracleのPIVOTについて教えてください。

syncrock

総合スコア209

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

Oracle Database 11g

Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

0グッド

0クリップ

投稿2016/09/21 00:17

編集2016/09/21 02:39

PIVOTのinに指定するグループ化対象列の値をどうにかして動的に変更できないでしょうか。

例えば、テーブルもしくはSELECT結果の項目として。
ユーザ、年月、売上
というものになってるとします。

それをPIVOTを使用して、
縦軸にユーザ、横軸に年月、値は売上のサマリーを用いたいです。

ただし、PIVOTのinにはグループ化対象列の値を直接入れる必要があると思ってます。
(for 年月 in ('201608','201609','201610') のような形で。)
ただ、年月の最大値はどんどん増えるので値を指定してしまうと
都度の変更が必要となるのでそれをどうにか出来ないか。というものです。

inの中の値を生成するfunctionを考えましたが、
複数の値を返すfunctionとなるとどーしてもtypeの型で返してしまうのでダメですよね・・・?
何かいい方法ないでしょうか。

-------追記---------

oracle

1create table test1 2( 3 item1 varchar2(10), 4 item2 varchar2(10), 5 item3 int 6) 7insert into test1 VALUES('A','2015',10) 8insert into test1 VALUES('A','2015',11) 9insert into test1 VALUES('A','2016',12) 10insert into test1 VALUES('A','2016',13) 11insert into test1 VALUES('B','2015',20) 12insert into test1 VALUES('B','2015',21) 13insert into test1 VALUES('B','2016',22) 14insert into test1 VALUES('B','2016',23)

例えばこのようなデータがあったとき。
やりたいことをSELECTで記載すると以下のようになります。

oracle

1select * 2from test1 3pivot (sum(item3) for item2 in('2015','2016'))

この時にinの中の文字列を直書きではなくしたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

現行のCREATE TABLEやSELECT文が提示されないとコメントが難しいかと。
PIVOTの使い方
第8回 PivotとUnPivot
などが参考にはなるかと。

投稿2016/09/21 01:19

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syncrock

2016/09/21 02:04

回答ありがとうございます。 すいません、現行しようとしてるのは複数のテーブルを結合した結果をPIVOTに しようとしてるので、ありのままを載せるのは量的にきびしいです、すいません。 (そもそも載せづらいのもありますが。) PIVOTの方法自体はわかるのですが、やはりinの中はSQLに値直書きしか無理。 ということでしょうか。
Orlofsky

2016/09/21 02:19 編集

全部載せろとは言いません。何をやりたいのか簡潔に説明できる内容であれば良いのです。贅肉を落としてシンプルにすることで自己解決できる場合も多いです。 IN には '201608','201609','201610' を結果として取得できるSELECTであれば良いです。
syncrock

2016/09/21 02:48

質問内容に追記させて頂きました。 例えば、 create table test2(item1 varchar2(10)) insert into test2 VALUES('2015') insert into test2 VALUES('2016') のデータを作り、 select * from test1 pivot (sum(item3) for item2 in(select test2.item1 from test2)) としましたが、式がありません。とエラーになるのですが単純にSQLが間違えていますでしょうか?
Orlofsky

2016/09/21 04:41

すみません。わたしの勘違いです。 >select * >from test1 >pivot (sum(item3) for item2 in(select test2.item1 from test2)) ではsyncrockさんが書かれたようにエラーになります。 ごめんなさい。
syncrock

2016/09/21 05:06

ということは、やはり何かしらの方法で実現させるのは難しそうですね。。。 ありがとうございました。
Orlofsky

2016/09/21 05:22 編集

以下を参考にEXECUTE IMMEDIATE で動的SQLを使えばできるかもしれませんが、試す気力はないです。 SET LINESIZE 100 SET PAGESIZE 100 SET SERVEROUTPUT ON DECLARE   CURSOR CUR_TA   IS     SELECT TA.TABLE_NAME        , 'SELECT /*+ INDEX_FFS(TA) */ COUNT(*) FROM ' || TA.TABLE_NAME || ' TA' AS SQL_STRING     FROM USER_TABLES TA     WHERE TA.DROPPED = 'NO' -- except trash box, since Oracle10.1.0     AND  TA.TABLE_NAME NOT IN       (       'CHAINED_ROWS' -- except Oracle side table      , 'EXCEPTIONS'      , 'PLAN_TABLE'       )     ORDER BY TA.TABLE_NAME ;   L_COUNTS NUMBER ; BEGIN   FOR REC_TA IN CUR_TA LOOP     EXECUTE IMMEDIATE REC_TA.SQL_STRING INTO L_COUNTS ;     DBMS_OUTPUT.PUT_LINE(RPAD(REC_TA.TABLE_NAME, 31) || TO_CHAR(L_COUNTS, '999,999,999,999,990')) ;   END LOOP ; END ; / 全角空白は半角空白2つに置換してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問