- - PR -
SQL Server 2005 の XQuery で OUTER JOIN
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2008-10-15 21:14
はじめまして。
現在、SQL Server 2005のXMLの機能を使って以下のようなバッチを作っています。 1.毎日テーブルからデータをXMLとして抽出し、ファイルに保存する。 2.当日分のXMLファイルと前日分のXMLファイルを比較して、変更点がわかるようにHTMLに表示する。 1の機能はFOR XMLを使用して実装できましたが、 2の機能のうち、当日分のXMLと前日分のXMLを比較する機能の実装ができません。 2の比較機能実装の手段として、以下のような処理を行っています。 (1)2つのXMLファイルを2つのテーブルのXML型の列にロードする。 (2)XML型の列からXQueryを使って列を抽出して、XMLのノード名を変えてUNION、変数に格納する。 (3)変数からXQueryを使って当日分、前日分を1つのノードにまとめ、XMLファイルとして出力する。 (4)XSLで前日分、当日分を比較できるよう、HTMLに出力する。 具体的なデータの流れで言うと、 (1)で元となるXML ・前日分 <名簿 No="1" 名前="太郎"> <住所 都道府県="東京都"/> <電話 優先順位="1" 番号="03xxxxxxxx"/> <電話 優先順位="2" 番号="090xxxxxxx"/> </名簿> <名簿 No="2" 名前="次郎"> <住所 都道府県="大阪府"/> <電話 優先順位="1" 番号="03xxxxxxxx"/> <電話 優先順位="2" 番号="090xxxxxxx"/> </名簿> ・当日分 <名簿 No="1" 名前="太郎"> <住所 都道府県="東京都"/> <電話 優先順位="1" 番号="03xxxxxxxx"/> <電話 優先順位="2" 番号="090xxxxxxx"/> </名簿> <名簿 No="2" 名前="次郎"> <住所 都道府県="大阪府"/> <電話 優先順位="1" 番号="03xxxxxxxx"/> </名簿> <名簿 No="3" 名前="三郎"> <住所 都道府県="京都府"/> <電話 優先順位="1" 番号="03xxxxxxxx"/> <電話 優先順位="2" 番号="090xxxxxxx"/> </名簿> (2)で作成したXML <当日分名簿 No="1" 当日分名前="太郎"> <当日分住所 当日分都道府県="東京都"/> <当日分電話 当日分優先順位="1" 当日分番号="03xxxxxxxx"/> <当日分電話 当日分優先順位="2" 当日分番号="090xxxxxxx"/> </当日分名簿> <当日分名簿 No="2" 当日分名前="次郎"> <当日分住所 当日分都道府県="大阪府"/> <当日分電話 当日分優先順位="1" 当日分番号="03xxxxxxxx"/> </当日分名簿> <当日分名簿 No="3" 当日分名前="三郎"> <当日分住所 当日分都道府県="京都府"/> <当日分電話 当日分優先順位="1" 当日分番号="03xxxxxxxx"/> <当日分電話 当日分優先順位="2" 当日分番号="090xxxxxxx"/> </当日分名簿> <前日分名簿 No="1" 前日分名前="太郎"> <前日分住所 前日分都道府県="東京都"/> <前日分電話 前日分優先順位="1" 前日分番号="03xxxxxxxx"/> <前日分電話 前日分優先順位="2" 前日分番号="090xxxxxxx"/> </前日分名簿> <前日分名簿 No="2" 前日分名前="次郎"> <前日分住所 前日分都道府県="大阪府"/> <前日分電話 前日分優先順位="1" 前日分番号="03xxxxxxxx"/> <前日分電話 前日分優先順位="2" 前日分番号="090xxxxxxx"/> </前日分名簿> Noが主キーとなっているので、Noだけ前日分、当日分という接頭語はつけないで変換しています。 ・・・ここまではうまくいっています。 問題はこの次です。 (3)で実行しているXQuery SELECT @x.query(' for $t in //当日分名簿 return for $y in //前日分名簿 where $y/@No=$t/@No return element 名簿{ attribute No{$t/@No}, attribute 当日分名前{$t/@当日分名前}, attribute 前日分名前{$y/@前日分名前}, for $tj in $t/当日分住所 return for $yj in $y/前日分住所 return element 住所{ attribute 当日分都道府県{$tj/@当日分都道府県}, attribute 前日分都道府県{$yj/@前日分都道府県}, }, for $td in $t/当日分電話 return for $yd in $y/前日分電話 where $td/@当日分優先順位=$yd/@前日分優先順位 return element 電話{ attribute 当日分優先順位{$td/@当日分優先順位}, attribute 前日分優先順位{$yd/@前日分優先順位}, attribute 当日分番号{$td/@当日分番号}, attribute 前日分番号{$yd/@前日分番号} } } ') as Result ; このXQueryを実行して、以下のような結果を得たいのです。 (いわゆる、FULL OUTER JOINをしたいのです。) <名簿 No="1" 当日分名前="太郎" 前日分名前="太郎"> <住所 当日分都道府県="東京都"/ 前日分都道府県="東京都"> <電話 当日分優先順位="1" 前日分優先順位="1" 当日分番号="03xxxxxxxx" 前日分番号="03xxxxxxxx"/> <電話 当日分優先順位="2" 前日分優先順位="2" 当日分番号="090xxxxxxx" 前日分番号="090xxxxxxx"/> </名簿> <名簿 No="2" 当日分名前="次郎" 前日分名前="次郎"> <住所 当日分都道府県="大阪府" 前日分都道府県="大阪府" 前日分番号="03xxxxxxxx"/> <電話 当日分優先順位="1" 前日分優先順位="1" 当日分番号="03xxxxxxxx"/> <電話 前日分優先順位="2" 前日分番号="090xxxxxxx"/> </名簿> <名簿 No="3" 当日分名前="三郎"> <住所 当日分都道府県="京都府"/> <電話 当日分優先順位="1" 当日分番号="03xxxxxxxx"/> <電話 当日分優先順位="2" 当日分番号="090xxxxxxx"/> </名簿> しかし、実際にやってみると以下のような結果にしかなりません。 (INNER JOINのような結果になっていしまいます。) <名簿 No="1" 当日分名前="太郎" 前日分名前="太郎"> <住所 当日分都道府県="東京都"/ 前日分都道府県="東京都"> <電話 当日分優先順位="1" 前日分優先順位="1" 当日分番号="03xxxxxxxx" 前日分番号="03xxxxxxxx"/> <電話 当日分優先順位="2" 前日分優先順位="2" 当日分番号="090xxxxxxx" 前日分番号="090xxxxxxx"/> </名簿> <名簿 No="2" 当日分名前="次郎" 前日分名前="次郎"> <住所 当日分都道府県="大阪府" 前日分都道府県="大阪府" 前日分番号="03xxxxxxxx"/> <電話 当日分優先順位="1" 前日分優先順位="1" 当日分番号="03xxxxxxxx"/> </名簿> (3)で実行しているXQueryの記述はW3CのXQuery 1.0 2006年06月勧告に記載 (日本語訳:http://t.kunishi.googlepages.com/xquery.html)されているLEFT JOINの記述を倣ったため、 FULL JOINとは行かないと思いますが、せめてLEFT JOINになってNo.3のノードが出力されることを期待していました。 長文になりましたが、同じ形式のXML文書をあるキーでOUTER JOINして1つのノードにまとめる方法をご教授いただければと思います。 |
|
投稿日時: 2008-10-20 11:22
解決しました。
私の私用の解釈の誤りでした。 どうやら、return句のところは、カンマが入るたびにfor句の参照が切れるようで、 この場合、LEFT JOINしたい項目1件ごとにfor〜returnを記述する必要があるようです。 詳しくは契約の関係上記載できません。ご了承ください。 ありがとうございました。 |
1