初歩的なSQLの質問で申し訳ありません。
以前にも同じような内容で投稿させて頂きましたが、教えて下さい。
下記のような、ある異なる名前の同項目を持つ2つのテーブルが存在します。
《テーブル》
Aテーブル
社員番号、日付、内容、所属、時間、結果
Bテーブル
社員番号、日付、内容、理由
※ 内容に関しては、AテーブルとBテーブルで全く違います。
これらの2つのテーブルをマージさせ、社員番号毎の内容毎、日付順に
したいと考えています。
以前に以下のようなUNIONを教えてもらいましたが、所属、時間、結果、理由という
項目全てを出力するとした場合、どのように記載すれば良いでしょうか?
UNIONの場合、項目が異なるとエラーとなってしまうかと、、、
《UNIONのSQL》
SELECT *
FROM (
SELECT 社員番号, 日付, 内容
FROM Aテーブル
UNION
SELECT 社員番号, 日付, 内容
FROM Bテーブル
)
ORDER BY 日付, 社員番号, 内容
教えて下さい。
よろしくお願いします。
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する項目順を入れ替えたり、不要な項目を削除したりすれば少しは楽になるかもしれません。
No.2
- 回答日時:
すみません。
質問をきちんと読めていませんでした・・・Bテーブルだけに存在する項目もあるのですね。
であれば、AテーブルのSELECT文でNULLを設定すればいいです。
SELECT 社員番号, 日付, 内容, 所属, 時間, 結果, NULL AS 理由
FROM Aテーブル
UNION
SELECT 社員番号, 日付, 内容, NULL, NULL, NULL, 理由
FROM Bテーブル
ORDER BY 社員番号, 内容, 日付;
でいかかでしょうか。
yamada_g様、ご回答ありがとうございます。
返事が遅くなりまして申し訳ありません。
教えて頂いた件、問題なくできました!
ちなみに、もしこれらのテーブルが複数存在し、社員番号、日付、内容は
キーになるものの、それ以外の項目を、テーブルがある分だけ表示させるような
場合はどのようにするのが良いのでしょうか?
1つ1つNULLを設定するのは難しいかと、、、
よろしくお願いします。
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.内容, 日付;
みたいな感じです。
yamada_g 様、ご回答ありがとうございます。
NULLの件ですが、Bテーブルの方も社員番号、日付、内容だけでなく、理由
も出力したいと考えています。
その場合は、NULLでは難しいですよね、、、
また、残念ながら両テーブルは、社員番号と日付では一意にならず、N:Nの
関係となっています。
何もわからず申し訳ありませんが、もう少し教えて頂ければ幸いです。
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle 下記のsqlで取得されるレコード以外を取得する方法ありますでしょうか。 SELECT B.番号, B 2 2022/04/20 23:21
- Oracle 質問です。 下記のテーブルとデータがあり、 取得想定結果のように出力したいです。 下記のsqlだと0 2 2023/05/23 19:10
- Oracle sqlで質問です。 Aテーブルの登録番号をキーにBテーブルから確認番号を取得したいのですが、Bテーブ 4 2023/05/18 13:08
- PostgreSQL postgreSQL カラムの全ての値を取得したい 3 2022/10/07 12:33
- Oracle sqlで質問です。 Aテーブルの情報をBテーブルに更新かけたいです。 やりたいことは、Bテーブルの受 1 2023/05/17 11:17
- SQL Server [SQLServer] テーブル名からカラム名を取得する 1 2022/08/23 21:20
- Oracle sqlのupdate文で質問です。 テーブルBの番号をキーにテーブルAの身長をテーブルBの身長に更新 2 2022/11/02 15:15
- Ruby pandasでsqlite3にテーブル作成・追加・読み出しでindexの取り扱い方教えてください 5 2023/03/08 09:57
- Oracle update文で質問です。 下記の条件でupdateをしたいですが、どのようにしたら良いでしょうか。 2 2022/06/23 10:51
- MySQL PhpMyAdminで作成して実行せよ。 東京23区を、皇居を中心とした4つのエリア(南東, 南西, 1 2023/06/11 11:58
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「マスタ」と「テーブル」の違...
-
重複するキーから一番古い年月...
-
2つのテーブルから条件に一致...
-
行方向のデータを横に並べる
-
sqlのupdate文で質問です。 テ...
-
主キーの変更
-
下記のsqlで取得されるレコード...
-
accessで移動平均する方法
-
続.ORACLEのSELECTのソートに...
-
ACCESS 一つのフィールドに複...
-
【Access】順位を付けたい
-
SQLの書き方(UPDATE文)
-
連番のMin, Maxを取得したい
-
動的SQL (その2)
-
Accessでフィールドを比較した...
-
Accessユニオンクエリーで2つ...
-
【SQL】group byについて
-
SELECT時にカウントアップ
-
Inner join と Left joinの明...
-
PLSQLの識別子エラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「マスタ」と「テーブル」の違...
-
2つのテーブルから条件に一致...
-
重複するキーから一番古い年月...
-
ACCESS 一つのフィールドに複...
-
PLSQLの識別子エラー
-
主キーの変更
-
Accessでフィールドを比較した...
-
SQL 2つのテーブルとSUBSTRING...
-
続.ORACLEのSELECTのソートに...
-
行方向のデータを横に並べる
-
下記のsqlで取得されるレコード...
-
VIEWでテーブルの集計結果...
-
update文で質問です。 下記の条...
-
[Oracle] UPDATE分の副問い合わ...
-
自分自身への矢印
-
片方だけ抽出する方法(SQL)
-
Accessユニオンクエリーで2つ...
-
連番のMin, Maxを取得したい
-
Inner join と Left joinの明...
-
日付の最大値を検索条件にする方法
おすすめ情報