ついに夏本番!さぁ、家族でキャンプに行くぞ! >>

お世話になります。

SQLについての質問です。

RDBMSはSymfowareです。

IN句に副問い合わせを指定するSQLと
その副問い合わせの結果を直接IN句に記載したSQLで
結果が異なってしまいます。

こういうことってありますでしょうか。

以下のようなSQLです。

(1)
SELECT
*
FROM
T1
WHERE
T1.column_A IN (
SELECT T2.column_A FROM T2 WHERE T2.column_B='XXXX'
)

上記IN句内のSELECT文の結果は、'A'、'B'、'C'、'D'です。

(2)
SELECT
*
FROM
T1
WHERE
T1.column_A IN ('A','B','C','D')

この(1)、(2)のSQLの結果が異なってしまいます。

私の環境では(1)では0件、(2)では2件ヒットします。

なぜこのようになるのかわかる方がいらっしゃいましたら
ご教授ください。

ちなみに、DBを操作して、副問い合わせのSELECT文の結果を
'A'、'B'とすると同じ結果が得られます。

副問い合わせのSELECT文の結果が3件以上になると(1)のSQLの
結果は0件になってしまいます。

RDBMSの障害でしょうか・・・?

それとも、IN句に副問い合わせを使用する場合、
その副問い合わせの結果は2件以下にする必要がある
なんてルールがあったりするのでしょうか。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

> 上記IN句内のSELECT文の結果は、'A'、'B'、'C'、'D'です。



他に、NULL値が返ってきていませんか?

この回答への補足

質問者です。

すみません、追加でわかったことがありますので、補足欄使わせてください。

-------------------------
お世話になります。

本現象に関してさらに切り分けをすすめて、
新たなことがわかりました。

>上記IN句内のSELECT文の結果は、'A'、'B'、'C'、'D'です。

と書いた部分ですが、これは質問のため私が作ったものでして、
実機で動かした結果ではありませんでした(´Д`;)

現象発生時の副問い合わせの結果は、
実際はこのような簡易なものではありませんでした。

そこで、本当に実機で動かして得られた結果を以下に記載します。

・副問い合わせの結果→結果
という形式で書きます。

・'A'、'AA'→発生
・'A'、'B'→発生せず
・'A'、'B'、'C'→発生せず
・'AB'、'ABC'→発生
・'AB'、'ABC'、'B'→発生
・'B'、'BA'→発生

という感じで副問い合わせの結果間で文字列が
前方一致しているものが存在する場合に発生するようです。

SQLってこういうものなのでしょうか?

副問い合わせの結果の件数とは関係なかったようです。
申し訳ありません。

補足日時:2011/04/28 11:11
    • good
    • 0
この回答へのお礼

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

副問い合わせで検索している項目はNOT NULL制約があり、NULL値は返ってきていません。

困りました。。。

お礼日時:2011/04/28 08:49

> IN句に副問い合わせを使用する場合、


> その副問い合わせの結果は2件以下にする必要がある
> なんてルールがあったりするのでしょうか。

ありません。
即値でIN句を使う場合は、指定できる即値について制限
がある場合はありますが。(Oracleなら1000個まで)
本当におっしゃっている現象が起きているならsymfoware
の問題である可能性があるので富士通に相談されたほうが
いいと思います。

この回答への補足

お世話になります。

上の補足をアップしたあと、さらに調査を進めたところ、発生条件がよくわからなくなってきましたので、申し訳ないですが、質問は一旦閉めます。

もっと情報をまとめてから再度ご質問させていただきます。

ありがとうございました。

補足日時:2011/04/28 16:37
    • good
    • 0
この回答へのお礼

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

そうですよね。
私の理解が間違っているのかと思いました。

nora1962さんのおっしゃるとおり、一度開発元に問い合わせてみようと思います。

お礼日時:2011/04/28 08:47

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qupdate文で改行を入れる

こんにちは。
いつもお世話になっています。

update文を使用して、データに改行を入れたいのですが、どうすればよいでしょうか。

対象列のデータ型はVARCHAR2です。

例えばSQLPLUSから、
SPL>update 「テーブル名」set 「対象列」='あ改行い改行う改行'
を投入し、そのあと
select 「対象列」 from 「テーブル名」
とすると
SQL>あ
SQL>い
SQL>う
と出てくればよいんですが、
SQL>update 「テーブル名」set 「対象列」='あ\nい\nう\n'
としても
SQL>あ\nい\nう\n
と、「\n」が文字列としてでてきてしまいます。

SPL>update 「テーブル名」set 「対象列」='あ
2い
3う'
と投入すると、期待通りになるのですが、
そうではなく一行にまとめたいのですがどうすれば良いでしょうか。

Oracle9iを使用しています。
宜しくお願いいたします。

Aベストアンサー

こんにちわyukio200263さん
以下のSQL文でどうでしょうか?

UPDATE 「テーブル名」
SET 「対象列」= 'あ' || CHR(13) || CHR(10) ||'い'

ちょっと長くなってしまいますが、一行で可能です。

QOracle(オラクル)で、日付時刻型の検索方法について

質問させていただきます。
データベースはオラクルを使っていて、
SQL文で、抽出するときにエラーが出て困っています。

日付時刻型が「2005/05/26 19:13:00」という感じで入ってます。
2005/05/26 を抽出したいのですが、
BETWEEN '2005/05/26 00:00:00' AND '2005/05/26 23:59:59'

だと、エラーでできません。
どなた様か、ご教授よろしくお願いしますm(_ _)m

Aベストアンサー

日付検索を行う場合は、以下のように書式を含める必要があります。

col BETWEEN TO_DATE('2005/05/26 00:00:00','YYYY/MM/DD HH24:MI:SS') AND TO_DATE('2005/05/26 23:59:59','YYYY/MM/DD HH24:MI:SS')

ただ、厳密には

col >= TO_DATE('2005/05/26', 'YYYY/MM/DD')
AND
col < TO_DATE('2005/05/27', 'YYYY/MM/DD')

と書くべきでしょうね。

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

Q3つの表の外部結合

表A、B、Cの3つがあり、Aのすべての行を出力したいと考えています。
外部結合を用いるのだとは思うのですが、3つの表に対して行う場合の
書き方がわからず困っています。
ご教授いただけないでしょうか?
select * from a,b,c
where a.商品ID =b.商品ID (+) and b.商品ID (+) =c.商品ID (+)
としてみましたが、うまくいきませんでした。

Aベストアンサー

ansi構文の趣旨からいえば、結合条件と絞り込み条件は分けて書くので・・

select *
from a
left join b on (a.商品ID =b.商品ID)
left join c on (b.商品ID =c.商品ID)
where a.年月 = 任意の値

と書くのが一般的でしょうね。

QInner join と Left joinの明確な違いは?

Inner join と Left joinの違いがよくわかりません。
教えてください。

Aベストアンサー

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
4               NULL
5               NULL
6               NULL
の6レコードが出力されますが、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 INNER JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
の3レコードしか出力されません。

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3           ...続きを読む

Qテーブルからのselectにおいてデータの有無により結果をわけたい

id | point
----+-------
1 | 10
2 | 9
3 | 5
....
というテーブルがあるとします.
idを指定してpointを得たいのですが、そのidがこのテーブルに存在しない場合は空の結果ではなく0を返したいのです.
plpgsqlなどを使いif文で場合分けすればできることはわかっているのですがSQL文だけで(それもできれば1文で)これを実現する方法はあるでしょうか?
よろしくお願い致します。

Aベストアンサー

変則的ですが、これでよければidがユニークでなくても大丈夫ですし、集合関数を使わなくてもOKです。

select dm.id,case when ex1.point is null then 0 else ex1.point end from
(select ? as id) as dm left join ex1 on dm.id = ex1.id;

?を適当に変えてください。
chukenkenkouさんの発想はこれですよね。

QSYSユーザーでログインしたい

SQL plusでSYSユーザーでログインするにはどうすればよいのでしょうか?
SYSTEMユーザーやSCOTTユーザーではログインできるのですが、SYSユーザーになる方法がわかりません。
お願いします。

Aベストアンサー

>SQL plusでSYSユーザーでログインするにはどうすればよいのでしょうか?
特別なことする必要がないと思います。
ログインできない場合いろいろな原因が考えられます。
一番可能な原因は設定によってSYSユーザーNOMAL権限でログインできない場合あります。
この場合
sqlplus sys/パスワード@接続文字列 as sysdba
で試してください。


>SYSTEMユーザーやSCOTTユーザーではログインできるのですが、SYSユーザーになる方法がわかりません。
conn sys/パスワード@接続文字列 as sysdba

QSELECT文でINを使わずに検索したい

DBはoracle10gです。
テーブル(A_TBL)は以下の4つのカラムで構成されています。
seq_no(連番),key_1(個人番号),key_2(更新日),status(状態)
key_1が同一のレコードは、
最新のレコード(最新とは更新日の大きいレコード)以外のstatusを'0'から'4'にします。
例として実行前と実行後のテーブルは以下のような状態です。

【実行前】
seq_no,key_1,key_2,status
1,001,20080101,1
2,001,20080102,0
3,002,20080101,0
4,003,20080101,0
5,003,20080102,0
6,003,20080103,0
7,004,20080101,0
8,004,20080102,2

【実行後】
seq_no,key_1,key_2,status
1,001,20080101,1
2,001,20080102,0
3,002,20080101,0
4,003,20080101,4
5,003,20080102,4
6,003,20080103,0
7,004,20080101,4
8,004,20080102,2

以下のようなSQLを作成し、更新しようとしました。

update A_TBL
set status = '4'
where status = '0'
and seq_no not in (
select wk2.seq_no
from A_TBL wk2,
(select max(key_2) as key_2,
key_1 as key_1
from A_TBL
group by key_1) wk1
where wk2.key_1 = wk1.key_1
and wk2.key_2 = wk1.key_2
and wk2.status = '0'
)

このSQLはin句を使っていますが、
in句を使わずに同様の更新を実現することは出来るでしょうか?

DBはoracle10gです。
テーブル(A_TBL)は以下の4つのカラムで構成されています。
seq_no(連番),key_1(個人番号),key_2(更新日),status(状態)
key_1が同一のレコードは、
最新のレコード(最新とは更新日の大きいレコード)以外のstatusを'0'から'4'にします。
例として実行前と実行後のテーブルは以下のような状態です。

【実行前】
seq_no,key_1,key_2,status
1,001,20080101,1
2,001,20080102,0
3,002,20080101,0
4,003,20080101,0
5,003,20080102,0
6,003,20080103,0
7,004,20080101,0
8,004,200...続きを読む

Aベストアンサー

昨日(No.2)は簡単に済ませて失礼しました。眠かったもので(笑)。

> in句でもカンマ区切りで指定した場合は1000件までで、
> 副問合せであれば問題なしという記述もありました。

こちらが正解でしょう。1000件というのは「式のリスト」の制限ですね。
下はマニュアルの抜粋です。

> カンマで区切られた式のリストには、最大1000個の式を指定できます。
> カンマで区切られた式の集合のリストには、任意数の式の集合を含める
> ことができますが、各集合に指定できる式は最大1000個です。

http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19201-02/expressions.html

SELECT文で指定してやる分には問題ないと思いますよ。

【実験】

SQL> select count(*)
2 from (
3 select level
4 from dual
5 connect by level <= 2000
6 );

COUNT(*)
--------
2000

1行が選択されました。

SQL> select ename, sal
2 from emp
3 where sal in (
4 select level
5 from dual
6 connect by level <= 2000
7 );

ENAME SAL
---------- --------
SMITH 800
ALLEN 1600
WARD 1250
MARTIN 1250
TURNER 1500
ADAMS 1100
JAMES 950
MILLER 1300

8行が選択されました。

# inの使用に問題がないのであれば……

update A_TBL
set status = '4'
where seq_no in (
select seq_no
from (
select seq_no, key_2, status,
max(key_2) over (partition by key_1) as max_key_2
from A_TBL
)
where key_2 <> max_key_2 and status = '0'
)

でいいかもしれません。

昨日(No.2)は簡単に済ませて失礼しました。眠かったもので(笑)。

> in句でもカンマ区切りで指定した場合は1000件までで、
> 副問合せであれば問題なしという記述もありました。

こちらが正解でしょう。1000件というのは「式のリスト」の制限ですね。
下はマニュアルの抜粋です。

> カンマで区切られた式のリストには、最大1000個の式を指定できます。
> カンマで区切られた式の集合のリストには、任意数の式の集合を含める
> ことができますが、各集合に指定できる式は最大1000個です。

http:...続きを読む

QSQL文について(片方のテーブルに存在しないレコード抽出)

以下のような2つのテーブルがあったとして、
2つともに存在する「店コード」を抽出するのはSQLは分かるのですが、
片方に存在しない「店コード」(以下の例の場合、「2」)を抽出するSQLを
一文で書くにはどうすればいいのでしょうか?

<店テーブル>
店コード住所・・・(その他、基本情報)
1aaa
2bbb
3ccc

<販売テーブル>
店コード販売品目・・・(その他、販売数など)
1xxx
3zzz

Aベストアンサー

オプティマイザ次第だけど、NOT-INは、あまりお勧めでない。
外部結合も索引があっても有効に使われないので、お勧めでない。

select * from A where not exists(select 1 from B where A.店コード=B.店コード);

Q実行計画の「COST」と「BYTE」について教えていただきたいです。

実行計画の「COST」と「BYTE」について教えていただきたいです。

書籍には
COST・・・・CBOによって見積もられた操作コスト。
BYTE・・・・アクセスされるバイト数のCBOのアプローチによる見積もり。
と書かれていますが、いまいちピンときません。


私は、
COSTは、検索するテーブルのデータ量が多いほうがコスト値が大きくなる。
BYTEは、検索条件に合致して取得できるデータが多いほうがバイト値が大きくなる。
と思っているのですが、正しいでしょうか?

Aベストアンサー

このあたりを参考にしてください。
COSTはデータ量だけではなく、その表やViewのアクセスに要する時間やSortや結合が必要なら、そのために必要なCPU時間等も考慮されています。
表があるHDDのアクセス速度なんかも考慮されているし、表のエクステントが複数になっているかとかも考慮されています。
書籍はわかりにくいかもしれませんが、嘘は少ないと思います。著者が思い違いをしてないとは言い切れませんが。

参考URL:http://otn.oracle.co.jp/forum/message.jspa?messageID=35016743


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング