- PR -

UNION後のJOIN方法

1
投稿者投稿内容
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-03-10 16:53
お世話になります。

SQLサーバー2000(SP4)でストアドプロシージャを開発しています。

UNIONについて質問があります。
以下のようなSELECT文を実行し、TABLE1とTABLE2からNOとTEXTを取得します。
その結果に対してさらにTABLE3をJOINしNAMEを取得したいのですが、UNIONで得た結果に対してJOINする方法が分かりません。
TABLE1とTABLE3、TABLE2とTABLE3をそれぞれ別々にJOINし、その後にUNIONしても同じ結果になると思うのですが、実際のSQL文では複雑なJOINを行っているのでTABLE3をJOINするのは1回にしたいと考えています。
どなたかアドバイスを頂けないでしょうか?
よろしくお願いします。

■UNION句
SELECT NO, TEXT FROM TABLE1
UNION
SELECT NO, TEXT FROM TABLE2

■JOIN句
LEFT OUTER JOIN TABLE3 T3 ON (NO = T3.NO)

■TABLE1
NO |TEXT
-------------
1 |あいうえお
2 |かきくけこ

■TABLE2
NO |TEXT
-------------
3 |さしすせそ
4 |たちつてと

■TABLE3
NO |NAME
-------------
1 |あ行
2 |か行
3 |さ行
4 |た行




こあら
大ベテラン
会議室デビュー日: 2007/06/26
投稿数: 157
投稿日時: 2008-03-10 17:27
インラインビューを使えばできると思います。
コード:
SELECT NO, TEXT, NAME FROM
(SELECT NO, TEXT FROM TABLE1 
 UNION 
 SELECT NO, TEXT FROM TABLE2 ) V1
LEFT OUTER JOIN TABLE3 T3 ON (V1.NO = T3.NO) 



パフォーマンスのことを考えると、インラインビューよりも、
インデックス付きビューを定義した方が良いかもしれません。
それから(確かなことは言えませんが)、
パーティションテーブルなど、調べてみた方が良い気もします。
http://www.atmarkit.co.jp/fdb/rensai/sqlstune03/sqlstune03_1.html
#リンク先は良く読んでないので見当違いだったら無視して下さい。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-03-11 08:28
こあらさん、いつもアドバイスありがとうございます。
現在開発中のプログラムは複雑で、その為試行錯誤しながら何回もこの掲示板でアドバイスを頂いてます、ほんとうに助かっています^^

まだこあらさんのSELECT文はうまく実現できていいません。
こあらさんのSELECT文を例にさせて頂くと、下記@では正常に結果が返ってくるのですが、下記Aにしたらエラーが表示されました。

@(UNIONをカッコでくくっただけの状態)→OK
(SELECT NO, TEXT FROM TABLE1
UNION
SELECT NO, TEXT FROM TABLE2 )

A(@の前に「SELECT * FROM」を付けた状態)→エラー
SELECT * FROM
(SELECT NO, TEXT FROM TABLE1
UNION
SELECT NO, TEXT FROM TABLE2 )

私は上記のSELECT文をリンク先サーバー(SQL2000)へOPENQUERYで実行しています。OPENQUERYだと実現できないとかはないですよね?私のコード記述ミスでしょうか?もう一度記述をチェックしてみます!
こあら
大ベテラン
会議室デビュー日: 2007/06/26
投稿数: 157
投稿日時: 2008-03-11 10:51
> エラー

どんなエラーなんでしょ?エラーコードとかキーワードぐらいは欲しいところです。

SQLServer2000ではインラインビュー(FROM句の副問合せ、サブクエリ)が使えないか、
別名の指定が必要か、でしょうか?

[追記]
http://www.microsoft.com/japan/technet/prodtechnol/sql/2000/books/sqlreskit0707.mspx

テーブル名としての SELECT ステートメントの使用
SQL Server および Oracle では、クエリを実行する際に SELECT ステートメントをテーブルのソースとして使用することができます。SQL Server では別名が必要ですが、Oracle では別名の使用はオプションです。
[/追記]


[ メッセージ編集済み 編集者: こあら 編集日時 2008-03-11 10:56 ]
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-03-11 11:01
こあらさん、追記です。

成功しました!!UNION句のかっこの後にエイリアス名がついていなかったからでした!

■エラー時
SELECT * FROM
(SELECT NO, TEXT FROM TABLE1
UNION
SELECT NO, TEXT FROM TABLE2 )

■OK時
SELECT * FROM
(SELECT NO, TEXT FROM TABLE1
UNION
SELECT NO, TEXT FROM TABLE2 ) V1 ← V1などのエイリアス名がないと下記のようなエラーが表示されるそうです。

■エラーメッセージ
サーバー : メッセージ 8180、レベル 16、状態 1、行 1
Statement(s) could not be prepared.
サーバー : メッセージ 170、レベル 15、状態 1、行 1
Line 6: Incorrect syntax near ')'.
[OLE/DB provider returned message: Deferred prepare は完了しませんでした。]

こあらさんの教えてくれたままのSQL文を使用すれば良かったのに、自分で加工した為にエイリアス名が抜けていました><;
これで次はUNION後にJOINする部分を試してみます!!

ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-03-11 11:05
こあらさん、すみません!
丁度書き込むタイミングが重なっててこあらさんの書き込みに気付きませんでした。
それに初歩的なミスでこあらさんの時間を割いて頂くようになって申し訳ありません。
リンクのサイト、参考にさせて頂きます!
ありがとうございます。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2008-03-11 13:40
自己レスです。

UNION後のJOIN、成功しました。
こあらさんの説明は分かり易くてほんと助かります!

今後ともよろしくお願いします。
失礼します。
1

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