DOBON.NET DOBON.NETプログラミング掲示板過去ログ

SQLでテーブルの読み方

環境/言語:[VB.NET]
分類:[.NET]

初歩的な事なのですが、教えてください。
WIN2000でVB.NETを使用しています(ただ、今回はSQLについての質問です)。

テーブルを1件づつ読み込んでいる途中で、同じテーブルをセレクトしたいのですが
可能でしょうか?
以下の様な事をしたいのです。

ループ開始
 テーブルAを1件読む
 テーブルBを1件読む
  テーブルAのレコードがBに有るかの存在チェックの為、BテーブルにSQLを発行
ループ終了

上の様な事は出きるのか、またテーブルBを1件づつ読んでいるポインタは狂って
こないのか、知っている方教えて下さい。
お願いします。
ひとつのSQLでできるかもしれません。

テーブルAとテーブルBでJOINすればよいのでは。
teiさん御免なさい。
もう少し詳しく書きます。

履歴TBL
  品番 管理番号
  y1 1
y2 2
y3 3
x1 4

新規TBL
  品番 管理番号
y1 1
y2 2
x1 4
x2 5
y3 6

出力TBL
  品番 管理番号 削除区分
y1 1
y2 2
y3 3 1
x1 4
x2 5
y3 6

新規と履歴のTBLが有り、出力TBLを作成
 新規と履歴にデータが存在する時、そのまま出力
 履歴だけにデータが存在する時、削除区分を1にして出力
 新規だけにデータが存在する時、そのまま出力

*TBLにはKEY項目は無く、履歴の削除されたデータをセレクトし
 新規テーブルとセレクトしたものを、出力しようにも並び替えが出来ない為
 1レコードづつ読み込むしか順番を変えない方法は、ないのかと考えています
 (他に自分の頭では考えが浮かばない)。 

上記の事をしたいのです。
いい考えを、教えてください。
お願いします。
外部結合をして、
nullのフィールドの判定で
更新方法を分ければいいと思います。
> 外部結合をして、
> nullのフィールドの判定で
> 更新方法を分ければいいと思います。

付け加えて述べるなら、データベースによって外部結合の記述方法に若干違う場合があります。
最近のデータベースであれば、JOINが使えますが、使えないデータベースでは記述方法に気をつけてください。
また、nullの判定方法もデータベースによって違います。
繁松さんの要求どおりではありませんが簡単な方法を一つ。

削除区分をつけたいrowの抽出SQL
select 品番,管理番号
from 履歴TBL
where not exists
(select 品番,管理番号 from 新規TBL where 履歴TBL.管理番号 = 新規TBL.管理番号)
order by 管理番号(逆の場合はorder by 管理番号 DEC)

それ以外のrowの抽出SQL
select 品番,管理番号
from 新規TBL 
LEFT OUTER JOIN 履歴TBL ON 新規TBL.管理番号 = 履歴TBL.管理番号
order by 管理番号(逆の場合はorder by 管理番号 DEC)

で恐らく大丈夫でしょう(MySQL以外は)。
また要求どおりのものもやってみますが、SQL関連は使っているデータベースソフト
が何かによって解答が変わりますので、できるならデータベースソフトとバージョンをあげてください。
あと恐らく強制されているのでしょうが、今回のようなテーブル構成はありえない
ようにも思われます。テーブル構成を見直したほうがよいでしょうね。
SELECT
削除TBL.品番, 削除TBL.管理番号, ISNULL(新規TBL.管理番号,1) AS 削除区分
FROM (SELECT 品番, 管理番号 FROM 履歴TBL WHERE (NOT EXISTS
(SELECT 品番, 管理番号 FROM 新規TBL WHERE 履歴TBL.管理番号 = 新規TBL.管理番号))) 削除TBL FULL OUTER JOIN
新規TBL ON 削除TBL.管理番号 = 新規TBL.管理番号

以上のようなSQLで一応要求は達成されるはず。ただ上記ではSQLserverでしか
うまくいきません。ISNULLをCOALESCEに変えるとMySQLとACCESS以外で使えそう
ですが、手元にACCESSしかないため動作確認が途中までしかできてません。
なにか不具合があればまたレスしてください。
多くの方が回答されてますし既に解決済みかも知れませんけど、違う観点から少し。

No4533
> 新規と履歴のTBLが有り、出力TBLを作成
>  新規と履歴にデータが存在する時、そのまま出力
>  履歴だけにデータが存在する時、削除区分を1にして出力
>  新規だけにデータが存在する時、そのまま出力

 これは
  新規 ∩ 履歴 → 削除区分 : NULL
  履歴 \ 新規 → 削除区分 : 1
  新規 \ 履歴 → 削除区分 : NULL
を期待している、即ち
  新規     → 削除区分 : NULL
  履歴 \ 新規 → 削除区分 : 1
となれば良いということですよね。で、この二つの和集合が得たいと。
# ∩ は積集合、 \ は差集合を表す記号です。

 差集合は EXCEPT 、和集合は UNION で取得できますので、これらを使用すれば
お望みのことは可能かと思います。ただ、 UNION は兎も角 EXCEPT はサポートしてない
データベースもありますので、ご注意下さいませ。

# EXCEPT が使用できない場合は、りきさんの例 ( No4564 ) にあるように EXISTS を
# 用いた副問い合わせをする方法もあります。以下一例です。

    SELECT *, NULL AS 削除区分 FROM 新規TBL
    UNION
    SELECT *, 1 FROM 履歴TBL
        WHERE NOT EXISTS (
            SELECT * FROM 新規TBL
                WHERE 履歴TBL.品番     = 新規TBL.品番
                AND   履歴TBL.管理番号 = 新規TBL.管理番号)


> *TBLにはKEY項目は無く、履歴の削除されたデータをセレクトし
>  新規テーブルとセレクトしたものを、出力しようにも並び替えが出来ない為
>  1レコードづつ読み込むしか順番を変えない方法は、ないのかと考えています

 こちらの内容はよく解らなかったので、的外れかも知れませんけども‥‥
主キーなどが設定されてなくても並べ替えを行うことは可能ですよ。


No4568
 えっと‥‥この SQL だと 品番と管理番号の出力が NULL になることがあるのでは?>りきさん
# 勘違いだったらごめんなさい(^_^;)
> No4568
>  えっと‥‥この SQL だと 品番と管理番号の出力が NULL になることがあるのでは?>りきさん
> # 勘違いだったらごめんなさい(^_^;)

いやー会社のSQLSERVERをインストールしてNO4568のSQLを試してみると
大惨事になってました(スミマセン)。
UNION使ったことなかったので軽視していたけど、他に代替できなかったのね。
質問者の繁松さん、訂正してくださった深山さんごめんなさい。
以後気をつけます。

DOBON.NET | プログラミング道 | プログラミング掲示板