• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:テーブルのマージSQLに関して)

テーブルのマージSQLで複数項目を出力する方法

このQ&Aのポイント
  • AテーブルとBテーブルをマージさせ、社員番号と内容を日付順に並べ替える方法について教えてください。
  • UNIONを使用することで、異なる項目を持つテーブルをマージさせることができますが、所属、時間、結果、理由の項目を全て出力する方法はありますか?
  • UNIONの場合、項目が異なるとエラーとなってしまう可能性があります。どのように記載すれば良いでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.3

そもそもがUNIONの用途として正しくない気がしますしね。 複数のテーブルの同一キーのデータを簡単に取れないというのは、設計がよくないのではないかという気がします。 >1つ1つNULLを設定するのは難しいかと、、、 とありますが、ただ面倒だということですよね? ひとつひとつ項目を列挙していくだけなので難しいことはないと思うのですが。 たしかに、テーブルや項目が多ければ大変だとは思いますが、やらなければいけないことならやるしかないと思います。 役に立つか分かりませんが、複数のテーブルの全項目をUNIONで取得するSQLを組み立てるSQLを考えてみました。 --全角スペースでインデントしています select   case     when COL_NUM = 1 then       case         when TAB_NUM > 1         then 'UNION ALL' ||CHR(10)       end       || 'SELECT' || CHR(10)     else ','   end || coalesce(P_COLUMN_NAME, 'NULL') || ' AS ' || L_COLUMN_NAME || case     when max(COL_NUM) over() = COL_NUM then       CHR(10) || 'FROM ' || TABLE_NAME   end from   (     select       TABS.TABLE_NAME      , COLS.COLUMN_NAME L_COLUMN_NAME      , TAB_COLS.COLUMN_NAME P_COLUMN_NAME      , dense_rank() over(order by TABS.TABLE_NAME) TAB_NUM      , ROW_NUMBER() over(partition by TABS.TABLE_NAME order by COLS.COLUMN_NAME) COL_NUM     from       (         select distinct COLUMN_NAME         from USER_TAB_COLS         where TABLE_NAME in ('Aテーブル', 'Bテーブル') --対象のテーブルを列挙してください       ) COLS     cross join       (         select TABLE_NAME         from USER_TABLES         where TABLE_NAME in ('Aテーブル', 'Bテーブル') --対象のテーブルを列挙してください       ) TABS     left join USER_TAB_COLS TAB_COLS     on       (         TAB_COLS.TABLE_NAME = TABS.TABLE_NAME       and TAB_COLS.COLUMN_NAME = COLS.COLUMN_NAME       )   ) order by   TAB_NUM  , COL_NUM ; これを実行すると、たとえば今回提示されているテーブル定義であれば、 SELECT 内容 AS 内容 ,所属 AS 所属 ,日付 AS 日付 ,時間 AS 時間 ,NULL AS 理由 ,社員番号 AS 社員番号 ,結果 AS 結果 FROM Aテーブル UNION ALL SELECT 内容 AS 内容 ,NULL AS 所属 ,日付 AS 日付 ,NULL AS 時間 ,理由 AS 理由 ,社員番号 AS 社員番号 ,NULL AS 結果 FROM Bテーブル というSQLが出来ます。 これをインラインビューにして、SELECTする項目順を入れ替えたり、不要な項目を削除したりすれば少しは楽になるかもしれません。

その他の回答 (2)

  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.2

すみません。質問をきちんと読めていませんでした・・・ Bテーブルだけに存在する項目もあるのですね。 であれば、AテーブルのSELECT文でNULLを設定すればいいです。 SELECT 社員番号, 日付, 内容, 所属, 時間, 結果, NULL AS 理由 FROM Aテーブル UNION SELECT 社員番号, 日付, 内容, NULL, NULL, NULL, 理由 FROM Bテーブル ORDER BY 社員番号, 内容, 日付; でいかかでしょうか。

asamix_000
質問者

お礼

yamada_g様、ご回答ありがとうございます。 返事が遅くなりまして申し訳ありません。 教えて頂いた件、問題なくできました! ちなみに、もしこれらのテーブルが複数存在し、社員番号、日付、内容は キーになるものの、それ以外の項目を、テーブルがある分だけ表示させるような 場合はどのようにするのが良いのでしょうか? 1つ1つNULLを設定するのは難しいかと、、、 よろしくお願いします。

  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.1

存在しない項目にNULLを設定すればUNIONすることができます。 SELECT 社員番号, 日付, 内容, 所属, 時間, 結果 FROM Aテーブル UNION SELECT 社員番号, 日付, 内容, NULL, NULL, NULL FROM Bテーブル ORDER BY 社員番号, 内容, 日付; もし、それぞれのテーブルが社員番号と日付で一意になり、それらのデータは1行にしたいということであれば完全外部結合してもいいと思います。 SELECT NVL(A.社員番号, B.社員番号) AS 社員番号, NVL(A.日付, B.日付) AS 日付, A.内容 AS A内容, B.内容 AS B内容, A.所属, A.時間, A.結果 FROM Aテーブル A FULL OUTER JOIN Bテーブル B ON (A.社員番号 = B.社員番号 AND A.日付 = B.日付) ORDER BY 社員番号, A.内容, B.内容, 日付; みたいな感じです。

asamix_000
質問者

お礼

yamada_g 様、ご回答ありがとうございます。 NULLの件ですが、Bテーブルの方も社員番号、日付、内容だけでなく、理由 も出力したいと考えています。 その場合は、NULLでは難しいですよね、、、 また、残念ながら両テーブルは、社員番号と日付では一意にならず、N:Nの 関係となっています。 何もわからず申し訳ありませんが、もう少し教えて頂ければ幸いです。 よろしくお願いします。