- PR -

テーブルの結合

投稿者投稿内容
パンダ
ベテラン
会議室デビュー日: 2004/03/24
投稿数: 59
投稿日時: 2004-09-09 18:13
テーブルA〜Cを結合してテーブルZを作成したと考えています。
SQL1発でデータを取得したいのですが、可能でしょうか?

テーブルA
日付 数量A
5/13 12
5/15 62
5/17 76

テーブルB
日付 数量B
5/13 12
5/14 52
5/15 26

テーブルC
日付 数量C
5/12 74
5/14 12
5/16 11

テーブルZ(欲しいデータイメージ)
日付 数量A 数量B 数量C
5/12 12       74
5/13     12
5/14     52   12
5/15 62   26
5/16          11
5/17 76


よろしくお願いします。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-09-09 18:17
はい。可能です。

但し提示された情報だけで、他の要因は一切無視して
Oracleを想定しておりますのでご注意下さい。

# 編集追記、

ごめんなさい訂正致します無理でした。
理由は、存在しないデータはOralceでは表示できません。


[ メッセージ編集済み 編集者: はにまる 編集日時 2004-09-09 18:19 ]
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2004-09-09 18:30
テーブルAからのSelect
select 日付,数値A,null,null ;
テーブルBからのSelect
select 日付,null,数値B,null ;
テーブルCからのSelect
select 日付,null,null,数値C ;
をUnion Allして
日付,数値A,数値B,数値Cのテーブルが出来ると思います。
(SQLServerで確認しました。)
ただ、同一日付を持つデータが出てしまいまいました・・・。

--------
1発で取りたいのならUnionしたものをViewにして
Viewに対してSQL発行すればいいのかもって、投稿後思いました。
(性能面はわからないのですが)

[ メッセージ編集済み 編集者: 夏椰 編集日時 2004-09-09 18:32 ]
たけだ
会議室デビュー日: 2004/09/09
投稿数: 7
投稿日時: 2004-09-09 19:01
こんなSQLでできました。(SQLServer2000で確認)
ちと汚いですが。
select 日付,
sum(case 区分 when 'A' then 数量 end) 数量A,
sum(case 区分 when 'B' then 数量 end) 数量B,
sum(case 区分 when 'C' then 数量 end) 数量C
from
(select 日付,数量A 数量,'A' 区分 from T_A
union
select 日付,数量B 数量,'B' 区分 from T_B
union
select 日付,数量C 数量,'C' 区分 from T_C) a
group by 日付
ゆう
ベテラン
会議室デビュー日: 2003/06/20
投稿数: 56
投稿日時: 2004-09-09 19:02
こんにちわ。

引用:

夏椰さんの書き込み (2004-09-09 18:30) より:
テーブルAからのSelect
select 日付,数値A,null,null ;
テーブルBからのSelect
select 日付,null,数値B,null ;
テーブルCからのSelect
select 日付,null,null,数値C ;
をUnion Allして
日付,数値A,数値B,数値Cのテーブルが出来ると思います。
(SQLServerで確認しました。)
ただ、同一日付を持つデータが出てしまいまいました・・・。



UNION ALL したものをサブクエリにして、数値A〜数値Cそれぞれを日付毎に
SUMしたらいかがですか? nullのところを0にするなりすれば
うまくいきそうな気がします。
#Oracleを想定してます。
HIRO
常連さん
会議室デビュー日: 2003/04/15
投稿数: 20
投稿日時: 2004-09-09 19:04
夏椰さんの補足として。
SQLServer2000の場合は以下のようにするとTABLE-Zが得られます。

※恐らく元投稿に一箇所データミスがあると思われますが、脳内変換しました

コード:
SELECT 日付, Sum(数量A) as A, Sum(数量B) as B, Sum(数量C) as C
FROM (
  SELECT 日付, 数量A, 0 as 数量B, 0 as 数量C FROM T1
    UNION ALL
  SELECT 日付, 0 as 数量A, 数量B, 0 as 数量C FROM T2
    UNION ALL
  SELECT 日付, 0 as 数量A, 0 as 数量B, 数量C FROM T3
) AS TMP
GROUP BY 日付



また、ZEROを空白に置き換える必要があるなら、CASEステートメントを使えば
どうでしょう。

コード:
SELECT 日付, 
Case Sum(数量A) when 0 then '' else cast(Sum(数量A) as varchar) end as A,
Case Sum(数量B) when 0 then '' else cast(Sum(数量B) as varchar) end as B,
Case Sum(数量C) when 0 then '' else cast(Sum(数量C) as varchar) end as C
FROM (
  SELECT 日付, 数量A, 0 as 数量B, 0 as 数量C FROM T1
    UNION ALL
  SELECT 日付, 0 as 数量A, 数量B, 0 as 数量C FROM T2
    UNION ALL
  SELECT 日付, 0 as 数量A, 0 as 数量B, 数量C FROM T3
) AS TMP
GROUP BY 日付

パンダ
ベテラン
会議室デビュー日: 2004/03/24
投稿数: 59
投稿日時: 2004-09-09 19:17
皆様、ありがとうございます。

すみません。DBはORACLEでした。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-09-09 22:26
あれれ?仕様確認が一切無しで終わりましたね。

パンダさんへ>
当投稿に対する返答は不要です。

SQLは
1.単に結果を出すだけの文法、
2.パフォーマンスを考慮した文法、
3.仕様を明示化した文法
が記述出来ますので、自分で好きなSQLを選べるように
テーブル構成と自分がわかる範囲での仕様のまとめを提示された方が良いです。

SQL文や関数はDBによって異なるのでDBの提示も重要ですが、
テーブル構成上のユニーク項目の提示も重要です。
今回の話で言えば、日付が一意で無い場合、想定外の結果になる可能性があります。

出来れば、パフォーマンスも考慮するためにインデックスも提示して下さい。

後、提示のサンプルパターンですが
元テーブルの日付に飛び番が存在するのに、要求される集計結果の日付が連番だったので
テーブルA,B、Cに存在しない日付のパターン提示が必要だったと思います。

御判りでしょうが、皆さんが提示されているSQL文は全て
日付を暗黙的に一意項目だと想定し、
テーブルA,B、Cに存在しない日付のレコードは表示しない仕様です。

スキルアップ/キャリアアップ(JOB@IT)