- PR -

検索結果が得られない検索条件を調べるには

投稿者投稿内容
lutein
会議室デビュー日: 2007/10/06
投稿数: 4
投稿日時: 2007-10-06 21:16
SQLServerのsql文で質問です。

SELECT * FROM User where User.ID IN (@param) 
※@paramには '1111','2222','XXXX','YYYY'が入っています。
'XXXX'と'YYYY'のIDの結果が得られない場合(Userテーブルに該当データが存在しない) は、結果が得られなかった検索条件、ここでは'XXXX','YYYY'を判別したいのですが良い方法はありますでしょうか?

自分が考えている手法では
@paramに入っているIDをひとつづつ検索し、
SELECT count(*) FROM User where '1111'
countが'0'のデータで判別しようとしていますが、
もっとスマートな方法がありましたらご教授お願いします。
忠犬
大ベテラン
会議室デビュー日: 2006/05/01
投稿数: 109
投稿日時: 2007-10-06 23:21
提示された二つのSQLは、両方ともやりたいことと合っていませんが?

引用:

SELECT * FROM User where User.ID IN (@param) 
※@paramには '1111','2222','XXXX','YYYY'が入っています



@paramという変数には、'1111'や'2222'などの、何れかの値を1個しか入れられない
ので、もしSQLがこの通りなら、行が検索できたかどうかで判定できますけど?

もし、inで4個の値を指定したいなら、4個の変数を使う必要があります。

コード:
declare @param1 char(4);
declare @param2 char(4);
declare @param3 char(4);
declare @param4 char(4);
select @param1='1111',@param2='2222',@param3='aaaa',@param4='bbbb';
select * from tbl1 where id in(@param1,@param2,@param3,@param4);



検索できた値をチェックすれば、どのデータが存在しなかったか判別できると思い
ますけど?
どうしてもSQLを再度投げる方法でやりたいなら、count関数とcase式を組み合わせて
SQLを作ってみては?
lutein
会議室デビュー日: 2007/10/06
投稿数: 4
投稿日時: 2007-10-07 10:09
忠犬様

返答ありがとうございます。
分かりづらい説明文で申し訳ありませんでした。
やりたいことは

SELECT * FROM User where User.ID IN (@param) 
※@paramには '1111','2222','XXXX','YYYY'が入っています

↑を実行後、 where in 句の@paramの中から検索結果が得られなかった"ID"を特定するです。特定したIDを使って次処理をしたいと思っています。
@paramには先の処理で複数のIDを文字列連結によりつなげている為、このように複数のIDが入っています。

count関数とcase式の組み合わせは初めて知りました。
ご教授頂いた方法でできるか再考してみます。

べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-10-07 11:16
というか、@paramにカンマ区切りの文字列を設定して、INの中身にすることってできます?
@paramに  '1111','2222','XXXX','YYYY' を設定後
SELECT * FROM User where User.ID IN (@param)
このSQL単独で、期待するレコードがちゃんと取得できていますか?

SQLの中で完結したいんですか?それともプログラム上で判断でもいいんですか?
lutein
会議室デビュー日: 2007/10/06
投稿数: 4
投稿日時: 2007-10-07 11:55
べる様

返答ありがとうございます。

このSQL文で期待するレコードは取得できています。
取得できるのは'1111'と'2222'のデータです。
SQLで完結できるのであれば、SQLで。
できなければプログラム上で判断したいと考えています。
忠犬
大ベテラン
会議室デビュー日: 2006/05/01
投稿数: 109
投稿日時: 2007-10-07 19:42
コード:
SELECT * FROM User where User.ID IN (@param)



で、'1111','2222','XXXX','YYYY'のうち、一つを@param入れて検索しているという
ことですか?

コード:
select @param='''1111'',''2222'',''XXXX'',''YYYY'''



としている訳ではないですよね?

当方、SQL Server 2005 Expressで確認しましたが、上述の方法でないと、ヒットさせる
ことはできません。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-10-07 20:14
引用:

luteinさんの書き込み (2007-10-06 21:16) より:
SELECT * FROM User where User.ID IN (@param) 
※@paramには '1111','2222','XXXX','YYYY'が入っています。
'XXXX'と'YYYY'のIDの結果が得られない場合(Userテーブルに該当データが存在しない) は、結果が得られなかった検索条件、ここでは'XXXX','YYYY'を判別したいのですが良い方法はありますでしょうか?


ぱっと見、IN でダメなら NOT IN かな?と思ったのですが、そうではないですね。
リレーショナルデーターベース(RDB)の機能としては、差集合になりますので、MINUS を使うのが理論的にはスマートです。

したがって、
コード:
SELECT '1111'
UNION
SELECT '2222'
UNION
SELECT 'XXXX'
UNION
SELECT 'YYYY'
MINUS
SELECT User.ID FROM User


みたいな感じ?(優先順位ってどうなるんでしょう?)

ただ、今回の場合、実践として考えると、つぎのような問題があります。
(1) '1111','2222','XXXX','YYYY' がテーブルにないので、取り扱いにくい。
(2) UNION や MINUS などのように行単位の演算が出てくると、扱いにくい。
理論的には上述のように MINUS で良いのですが、使いにくいのです。そもそも Oracle ならまだしも SQL Server で MINUS ってあまり聞きません。

私だったら、とりあえず MINUS を試してみますが、でも、使いにくかったら、
SELECT * FROM User where User.ID IN (@param)
などの SQL で一旦結果を求めてから、'1111','2222','XXXX','YYYY' との比較を SQL 外のプログラムでやります。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-10-07 21:51
引用:

luteinさんの書き込み (2007-10-07 11:55) より:
べる様

返答ありがとうございます。

このSQL文で期待するレコードは取得できています。
取得できるのは'1111'と'2222'のデータです。
SQLで完結できるのであれば、SQLで。
できなければプログラム上で判断したいと考えています。

プログラム上でもかまわないなら素直にプログラムでやったほうがいいかもしれません。
渡すIDを覚えといて、SELECTした後で拾えていないIDをforeachかなんかで探すだけですよね。

しかし、私もいまだに忠犬さんと同じく、どうやって取得できてるのか理解できていません。
SELECT * FROM User where User.ID IN ('''1111'',''2222'',''XXXX'',''YYYY''')
を実行していることになるはずなんですが。

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