以下のSQLを実行した場合、レコードを1件取得して欲しいのですが、
なぜか上手く取得できません。
ご存知の方がいらっしゃいましたら、教えてください。
-- SQL1 ---------------------------------------------------
select
MAIN.MAIN_NAME,
nvl(SUB1.CODE is NULL, 0) as SUB_CODE1,
nvl(SUB2.CODE is NULL, 0) as SUB_CODE2
from
MAIN_TABLE MAIN
left join SUB_TABLE SUB1 on MAIN.CODE = SUB1.CODE
and SUB1.ZYOUKEN = '1' (1)
left join SUB_TABLE SUB2 on MAIN.CODE = SUB2.CODE
and SUB2.ZYOUKEN = '' (2)
where
MAIN.CODE = 'XXX'
-----------------------------------------------------------
質問1.
どうも、(2)の部分を空文字(?)ではなく何か値を入れると正常に1件
取得できるようなのですが、なぜ外部結合しているにもかかわらず
0件になってしまうのかが良く分かりません。
質問2.
やはり条件に空文字を使用するのはよろしくないでしょうか?
※補足
念のため、以下のSQLを実行したところ、こちらは問題なく1件取得
できているので、抽出条件は間違っていないです。
-- SQL2 ---------------------------------------------------
select
MAIN.MAIN_NAME
from
MAIN_TABLE MAIN
where
MAIN.CODE = 'XXX'
-----------------------------------------------------------
以上です。宜しくお願いします。
No.4ベストアンサー
- 回答日時:
autotrace あたりで自分の意図したとおりのものになっているか確認してみてはどうでしょう?
WHERE句が指定されているので、実行計画が等価結合に書き換わっちゃっている可能性があります。
昔、これではまったことがあるので
僕は外部結合するときはWHEREは指定しないようにして
ON句で条件を指定するようにしています。
# 個人的にはバグじゃないかと思うんだけど仕様らしい。
たとえば、
WHERE句の条件を(1)あたりに追加してみてうまくいくようならこのケースかなと。
なるほど!
私もバグのような気がしますが、仕様・・・ですか。
>>WHERE句の条件を(1)あたりに追加してみてうまくいくようならこのケースかなと。
社内に再現できる環境が無いので、次の機会に試してみます。
有難うございました。
No.3
- 回答日時:
とりあえず質問2についてですが、
NULL=NULLやNULL=''や''=''は真ではないですよ。
OracleにおいてNULLというのは「なんだかわからないもの」なので、
「なんだかわからないもの1」は「なんだかわからないもの2」と等しいかと聞いても、
「わからない」といわれてしまいます。
Select 'HOGE' From Dual Where NULL=NULL;
Select 'HOGE' From Dual Where NULL='';
Select 'HOGE' From Dual Where ''=NULL;
Select 'HOGE' From Dual Where ''='';
Select 'HOGE' From Dual Where NULL Is NULL;
Select 'HOGE' From Dual Where '' Is NULL;
この辺を実行して結果を確認してみてください。
Is NULL以外だと、NVL( HOGE, 'NULL' )='NULL'のような方法もあります。
個人的にはNo.1の方と同じくNULLは好きではないので、最初から固定長空白で埋める派です。
質問1について、
「1行取得したいのだが、上手く取得出来ない」というのは具体的にどのような状態でしょう?
Oracleエラーが出るだとか、レコードが選択されないだとか、複数選択されてしまうとか。
nvl(SUB1.CODE is NULL, 0) as SUB_CODE1,
という記述を初めて見るのですが、これはエラーが発生しませんか?
NVL( HOGE, 0 )
と記述すると、HOGEがNULLの時に0が返される、という関数だったと思うのですが。
この回答への補足
ご丁寧に有難うございます。
>NULL=NULLやNULL=''や''=''は真ではないですよ。
もちろんこれは承知しています。
私の書き方が悪かったようですみません。
No.1の方に補足させて頂きましたので、宜しければそちらご覧下さい。
>「1行取得したいのだが、上手く取得出来ない」というのは具体的にどのような状態でしょう?
レコードが1件も選択されない状態です。
>nvl(SUB1.CODE is NULL, 0) as SUB_CODE1,
という記述を初めて見るのですが、これはエラーが発生しませんか?
確かにこの記述はおかしいですね。
↓が正しいです。
nvl(SUB1.CODE , 0) as SUB_CODE1,
nvl(SUB1.CODE , 0) as SUB_CODE1,
No.1
- 回答日時:
>>SUB2.ZYOUKEN = ''
SUB_TABLEのZYOUKENの中身が「スペース」「NULL」ってことは?
空白条件にする場合は
RTRIM(LTRIM((SUB2.ZYOUKEN)) = ''とかよくやってますが。
オラクルじゃなくてSQLServerなので文法はお察しください。
ちなみに、NULLの場合は。。。大嫌いな処理なのでおいらが組む場合は極力NULLを使わないシステムにしてるので参考文は書きません。はい。
select
*
from
SUB_TABLE
where
ZYOUKEN = ''
これと同等ですよね。結合しなきゃですが。
この回答への補足
回答有難うございます。
>>SUB_TABLEのZYOUKENの中身が「スペース」「NULL」ってことは?
これは設計上ありえません。
なので、別にZYOUKENの中身が''のデータを取得したい訳では無いのです。
少々書き方が悪かったようですみません。
上記SQLでは(1),(2)の右辺を固定で'1'、''と記載しましたが、
正確には変数1、変数2です。
場合によっては変数の中身が無いことがあるので、その場合右辺が''となります。
また、上記SQLを実行する意図ですが、
1.MAIN_TABLEにCODE='XXX'のレコードが存在するか。
2.SUB_TABLEにCODE='XXX' かつ ZYOUKEN=変数1
のレコードが存在するか。
3.SUB_TABLEにCODE='XXX' かつ ZYOUKEN=変数2
のレコードが存在するか。
この3つのチェックを行いたいのですが、MAIN_TABLEにCODE="XXX"
のレコードが存在しているのに、結合条件が''になったときに
なぜデータが1件も取得できないのかが疑問に思ったところです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) ローマ字、ハイフン付きの並び替え ローマ字抽出方法 Excelマクロ 4 2022/04/01 14:10
- オープンソース Try Kotlinで readLine()を使うには 1 2023/03/27 21:06
- PHP DBのハッシュ化したパスワードをpassword_verifyで戻し照合したのですが上手く行きません 2 2023/02/06 13:24
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- Visual Basic(VBA) VBA リボンののリカバリーでオーバーフローエラーになります 2 2023/07/04 19:07
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- Java java 次の機能を有するメソッドを自クラスに作成し、実装したいです。 機能 名前判定機能 →名前が 3 2022/06/16 16:08
- Java javaの質問です 次の機能を有するメソッド4つを自クラスに作成し、実装したいです 【機能】 足し算 1 2022/06/15 17:49
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関係演算子が無効です。
-
9iのSQL:1999構文を使用した外...
-
GROUP BYを行った後に結合した...
-
SELECTで1件のみ取得するには?
-
Excelで、改行がある場合の条件...
-
Oracleでの文字列連結サイズの上限
-
SQL文で右から1文字だけ削除す...
-
Accessで別テーブルの値をフォ...
-
ADO VBA 実行時エラー3021
-
SQLの書き方(チェックボックス)
-
実績累計の求め方と意味を教え...
-
OracleのSQL*PLUSで、デー...
-
アクセスでレポートの1印刷内...
-
Accessでのレコード存在チェック
-
CREATE テーブルでの複数外部...
-
oracleのinsert select性能
-
チェックボックスの項目をDBにi...
-
Access終了時の最適化が失敗?
-
キーが同じを複数行を1行にま...
-
select insertで複数テーブルか...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関係演算子が無効です。
-
SQL 外部結合についての質問
-
Excel VBAで、Averageの範囲を...
-
TO_CHAR関数における外部結合に...
-
同じテーブルをLEFT JOIN
-
自己相関サブクエリと自己結合...
-
LEFT JOINの条件式で=’’を使用...
-
Informixで文字列を数値型に
-
内部結合する時の結合条件と制...
-
Access 結合条件設定方法
-
T-SQL 動的に優先順ごとにデー...
-
WHERE句の書き方
-
エラー「無効な識別子です」
-
エクセルVBAでSUM関数の位置を...
-
Pro*CでVARCHAR2項目の検索
-
エラー2「無効な識別子です」
-
Oracle SQL 結合の手法について
-
【修正希望】【マクロ】元デー...
-
SQLで後方の文字列を置換する方法
-
range表記をcells表記にしたい
おすすめ情報