![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
はじめまして。
現在、画面上で検索条件を選択し、検索ボタンを押すと結果を返すアプリケーションを作成しておりますが、
画面上の検索の条件に「空白」を加えると、検索前に空白で表示されていた件数に比べて少ない結果になる、という現象が起こっています。
原因は、テーブルAとテーブルBを外部結合させてデータを取得して表示していますが、
検索前はBにレコードを持たないデータも表示しており、対象項目に検索条件「空白」を設定すると、テーブルBにレコードを持ち、
かつ該当項目が空白(null)であるデータのみ検索して、テーブルBにレコードがないデータは検索されないため、検索前より件数が少なく表示されるためだと判明しました。
画面上空白が選択されたら、テーブルAの該当項目は空白、テーブルBにはデータを持たないレコードも表示したいのですが、
どのようにすればよいかご教示いただければ有難いです。
(検索条件は複数あり、空白を指定できる項目も複数あるという前提です。)
以上、よろしくお願い致します。
No.5ベストアンサー
- 回答日時:
なんとなく誤解があるんだろうなぁと思っていましたが。
。LEFT OUTER JOINの結果のNULLとレコード自体のNULLには何の違いもありません。NULLはNULLです。
以下で確認してください。質問者さんの考え方では、以下でもKEYID=2のレコードが抽出されることに
なりますが、実際には抽出されません。
DECLARE @TBLA TABLE ([KEYID][int],[F1][varchar](5))
DECLARE @TBLB TABLE ([KEYID][int],[F2][varchar](5))
INSERT INTO @TBLA VALUES (1,'X')
INSERT INTO @TBLA VALUES (2,'Y')
INSERT INTO @TBLA VALUES (3,'Z')
INSERT INTO @TBLB VALUES (1,'ABC')
INSERT INTO @TBLB VALUES (3,'BCD')
SELECT a.KEYID,a.F1,b.F2
FROM @TBLA a
LEFT OUTER JOIN @TBLB b ON b.KEYID=a.KEYID
WHERE b.F2='ABC'
回答が遅くなり、申し訳ありません。
実際に試したところ、LEFT JOINのWHERE句の検索内容に沿ったデータのみ抽出されました。
私自身の混乱の原因としては
(1)「*=」を使用していた際、where句の条件に「項目=Null」を入れていたところ全件ヒットしていた
(2)(1)により、外部結合では、結合される側をwhere句の条件で指定しても全件ヒットしてしまうものと思ってしまった
というところにあるようです。
(1)に関してはSQLserverのバージョンの問題で、曖昧な条件になってしまっているところに原因があるようですが、(2)に関しては外部結合が根本的に分かっていない(結合した後に抽出していることが理解できていない)ところに原因があるように思います。SQLをもっと勉強する必要がありますね。
この度はありがとうございました。
No.4
- 回答日時:
#2,#3です。
>ご提示いただいたSQLですと、検索の際、Bのnull以外の検索値を指定した場合、Bのテーブルに値を持っていないデータもヒットしてしまうかと思います。
そんなことはないですよ。
例えば、BのF4というカラムに"ABC"という条件を指定すると、条件にはb.F4='ABC'が追加されます。
ということはBに値のない(NULLの)レコードはヒットしないです。
一方、BのF4というカラムに""(空白)という条件を指定すると、条件には(b.F4='' OR b.F4 IS NULL)が追加されます。
したがって、この場合はBに値のない(NULLの)レコードもヒットします。
まあ、あくまで代案として載せたサンプルコードなので、理解できてもできなくても別にかまわないですが。。。
この回答への補足
分かりづらい表現ですみません。
「Bのテーブルに値を持っていないデータ」というのは、
テーブルAにはデータがあるが、Bには対応するデータがないレコード、という意味です。
LEFT OUTER JOIN の構造でBのF4というカラムに"ABC"という条件を指定すると、
・BにAと対応するデータを持っていて、かつb.F4='ABCであるレコード
・BにAと対応するデータを持っていないレコード
がヒットしてしまうのではないかと思います。
No.3
- 回答日時:
#2です。
結局検索条件に合わせてASPかVBScriptでSELECT文を組み上げているわけですよね?
書かれた案でもいいのでしょうけど、素朴な疑問として、AのフィールドとBのフィールドで検索条件の追加方法を変えるだけではだめなんでしょうか。
ざっくりこんな感じで。。
Dim sSQL,sWhere
sSQL = "SELECT a.KEY,a.F1,a.F2,a.F3,b.F4,b.F5,b.F6" & _
" FROM TABLEA a" & _
" LEFT OUTER JOIN TABLEB b ON b.KEY=a.KEY"
If bUseF1=True Then sWhere=sWhere & " AND a.F1='" & sF1 & "'"
If bUseF2=True Then sWhere=sWhere & " AND a.F2='" & sF2 & "'"
If bUseF3=True Then sWhere=sWhere & " AND a.F3='" & sF3 & "'"
If bUseF4=True AND sF4="" Then sWhere=sWhere & " AND (b.F4='' OR b.F4 IS NULL)"
If bUseF4=True AND sF4<>"" Then sWhere=sWhere & " AND b.F4='" & sF4 & "'"
If bUseF5=True AND sF5="" Then sWhere=sWhere & " AND (b.F5='' OR b.F5 IS NULL)"
If bUseF5=True AND sF5<>"" Then sWhere=sWhere & " AND b.F5='" & sF5 & "'"
If bUseF6=True AND sF6="" Then sWhere=sWhere & " AND (b.F6='' OR b.F6 IS NULL)"
If bUseF6=True AND sF6<>"" Then sWhere=sWhere & " AND b.F6='" & sF6 & "'"
If LEFT(sWhere,4)=" AND" Then sWhere = " WHERE" & RIGHT(sWhere,LEN(sWhere)-4)
sSQL=sSQL & sWhere
あとは、外部結合の書式ですが「*=」はSQL Server 2005からはサポートされませんから、「LEFT OUTER JOIN」に慣れておいた方がいいですよ。
この回答への補足
ご返答ありがとうございます。
ご提示いただいたSQLですと、検索の際、Bのnull以外の検索値を指定した場合、Bのテーブルに値を持っていないデータもヒットしてしまうかと思います。
(Bの検索値に空白以外の値を入力した場合、検索結果はBにデータも持たないレコードを含まず、Bに検索値を持っているデータのみ表示させたい)
なお、空白が指定できる項目は、Bにある項目のみになります。
外部結合に関しては、ご教示いただきましたように、今回の修正でLEFT OUT JOINに変更する予定でおります。
No.2
- 回答日時:
画面がVBなのか、Accessなのか、それ以外なのか。
検索条件入力後のクエリはどのように構築しているか。・・が分からないので、純粋にSQL Serverに関する質問と考えて書きますが、
空白を指定できる検索条件が複数あったとしても、「空白またはNULL」の両方を満たすように条件を指定してあげるしかないと思います。
SELECT * FROM TABLEA a
LEFT OUTER JOIN TABLEB b ON b.KEY=a.KEY
WHERE a.FIELD1=@PARM1
AND ISNULL(a.FIELD2,'')=@PARM2
AND ISNULL(b.FIELD1,'')=@PARM3
AND ISNULL(b.FIELD2,'')=@PARM4 ...
テーブルAのうち、NULLの入らない項目についてはISNULLはかぶせないようにし、条件はできるだけ最初の方に持ってくるのがいいでしょう。
検索条件をできる限り触りたくない場合、結合しているテーブルの方をビューにして、ビューの中でテーブルB側の
項目に全部ISNULLをかぶせてしまう手もあるかと思います。
CREATE VIEW VIEWA
AS
SELECT
a.KEY1 KEY,
a.FIELD1 AFIELD1,
ISNULL(a.FIELD2,'') AFIELD2,
........
ISNULL(b.FIELD1,'') BFIELD1,
ISNULL(b.FIELD2,'') BFIELD2
FROM TABLEA a
LEFT OUTER JOIN TABLEB b ON b.KEY=a.KEY
で、検索するときには
SELECT * FROM VIEWA
WHERE AFIELD1=@PARM1
AND AFIELD2=@PARM2
AND BFIELD1=@PARM3
AND BFIELD2=@PARM4 ...
この回答への補足
状況に関する記述が不足していまして、申し訳ありません。
環境
開発言語:ASP DB:SQLserver
問題の箇所は検索ボタンを押してからの動作で、SQLを投げているのはVBScriptです。
Bの項目に含まれる検索項目に入力があるとフラグをオンにし、
フラグがオンの場合:AND A.KEY = B.KEY
フラグがオンでない場合:AND A.KEY *= B.KEY
という条件にしています。
検索条件にnullの入らない項目はSQL上前に集結させております。
現状、いただいた回答により以下のような案を考えました。
(1)Aにデータを持ち、Bにデータを持たないレコードをserectしたビュー(Vα)を事前に作成しておく
(2)検索時にnullが入る項目にすべてnullを指定された場合、
AとBにデータを持ち、かつ検索項目を満たすデータ(=内部結合で検索条件に一致するデータ)と、
Vαで検索条件に一致するデータをunionさせる
nullが入る項目に1つでもnull以外を指定された場合、Bにデータがあることが前提になるため、
Vαはunionさせない
上記の方法に矛盾がある、またはほかに方法がある場合、
ご教示いただければありがたいです。
No.1
- 回答日時:
こんばんは
データベースについては人様にアドバイスできるほどの経験はなく、自分自身が勉強しながら使ってる者です。
一番に思いつくのは外部結合のRIGHTとLEFTを間違っていませんか?ということです。
テーブルA、テーブルBのフィールドと問題のあるSQL文を提示してもらえれば、もう少しアドバイスできるかもしれません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Access(アクセス) Access 複数条件検索の設定が上手く行きません 1 2022/07/22 20:37
- Excel(エクセル) VLOOKUP が機能しない、その原因は何 ? 8 2022/10/19 12:06
- JavaScript html javascriptにてWeb SQLを操作したい。 2 2022/12/16 17:43
- Access(アクセス) Accessでセレクタをダブルクリックで別フォームで詳細表示 3 2022/12/20 10:36
- その他(データベース) Accessのクエリで1フィールドの抽出条件設定をNullでなく全角半角含む空白のみの文字列でない文 1 2023/04/24 15:20
- Access(アクセス) AccessVBAで降順にするテーブル作成クエリを使用して作成したテーブルを削除し同一のテーブル作成 1 2023/01/06 11:17
- Visual Basic(VBA) Excel VBAのリストボックスの値を他のフォームに反映させる方法を教えてください。 2 2023/07/14 14:06
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- Excel(エクセル) 非表示にしたい行をグループ化して折り畳み 4 2022/09/17 20:17
- Excel(エクセル) エクセルで、2つのセルに検索値を入れて結果を一覧表示させる 1 2023/07/10 10:26
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
データの二重表示の原因
-
3つ以上のテーブルをUNIONする...
-
Accessにインポートしたら並び...
-
Access 1レコードずつcsvで出力...
-
ACCESS【更新クエリの中断がで...
-
ACCESSファイルを開こうとする...
-
Access カレントレコードがあり...
-
非連結サブフォームのレコード...
-
SQLServerで同一条件レコードの...
-
数百万件レコードのdelete
-
SQLデータ修正時に『このレコー...
-
Access VBA Me.Requery レコー...
-
Access 削除クエリが重い
-
一部重複しているレコードの削除
-
ManagementStudioからのデータ削除
-
Accessでの排他制御
-
ACCESSのBookmarkプロパティの...
-
(ACCESS)並び替えをしないで...
-
2つのテーブルからのレコード取得
-
2つの項目が重複するレコード...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Accessにインポートしたら並び...
-
データの二重表示の原因
-
2つの項目が重複するレコード...
-
3つ以上のテーブルをUNIONする...
-
数百万件レコードのdelete
-
Access VBA Me.Requery レコー...
-
非連結サブフォームのレコード...
-
Access 削除クエリが重い
-
ACCESSのBookmarkプロパティの...
-
Access 1レコードずつcsvで出力...
-
ManagementStudioからのデータ削除
-
Accessの重複クエリで最小以外...
-
Accessでの排他制御
-
Accessで重複したデータを一件...
-
(ACCESS)並び替えをしないで...
-
フォームからのレコード削除に...
-
SQLServerで同一条件レコードの...
-
Accessでの禁止文字チェック
-
Accessでレコードが更新された...
-
テーブルのレコード削除ができ...
おすすめ情報