人に聞けない痔の悩み、これでスッキリ >>

ORACLE環境下、SQLにて以下のような条件でデータを取得したいです。

AテーブルとBテーブルを結合して、Bテーブルから名称を取得する。
<Aテーブル>
id (key) 番号1 番号2
A01  001  n0001
A02  null  n0002

<Bテーブル>
code(key) 名前  番号1 番号2
c0001   太郎  001  n0001
c0002   次郎  002  n0002

(1)A.番号が入力されていれば
A.番号1=B.番号1 AND A.番号2=B.番号2を条件にする

(2)A.番号が入力されていなければ
A.番号=B.番号を条件からはずす。
A.番号2=B.番号2 のみで検索する。

<欲しい結果>
A01→太郎を取得
A02→次郎を取得

入力されていたら条件に加え、入力されていなかったら
条件から外す、というSQLを教えていただけないでしょうか。
よろしくお願いいたします。

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

A 回答 (6件)

#5です。

Bテーブルとエイリアスが不足してました。

(1)と(2)をunionしてはどうでしょう?

select a.id, b.名前 from Aテーブル a, Bテーブル b where a.番号1 is not null and a.番号1 = b.番号1
union
select a.id, b.名前 from Aテーブル a, Bテーブル b where a.番号1 is null and a.番号2 = b.番号2
;
    • good
    • 0

(1)と(2)をunionしてはどうでしょう?



select a.id, b.名前 from Aテーブル where a.番号1 is not null and a.番号1 = b.番号1
union
select a.id, b.名前 from Aテーブル where a.番号1 is null and a.番号2 = b.番号2
;
    • good
    • 0

>nullの場合は条件から完全に外したいのです。


の意図がよく分かりません・・・
さきほどのSQLで希望の結果になると思うのですが。
SQLから消したいのであれば、プログラムで動的にSQLを組み立てればいいのではないでしょうか。
    • good
    • 0

No.1、No.2です。



何回かリロードしても回答が反映されていなかったので、再度回答したところ重複してしまいました。
すみません・・・
    • good
    • 1

orで二つの条件を書く。



select a.id, b.名前
from Aテーブル a
inner join Bテーブル b on (
(b.番号1 = a.番号1 and b.番号2 = a.番号2)
or
(a.番号1 is null and b.番号2 = a.番号2)
);

もしくは、Aテーブルの番号1がnullのときはBテーブルの番号1で結合する。
ただし、こちらの方法ではBテーブルの番号1にnullが入る場合はうまくいきません。

select a.id, b.名前
from Aテーブル a
inner join Bテーブル b
on (
b.番号1 = nvl(a.番号1,b.番号1) and b.番号2 = b.番号2
);

でどうでしょうか。

この回答への補足

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

nullの場合は条件から完全に外したいのです。
※番号1 is null の場合、nullで検索しない。

もし代案ありましたらよろしくお願いします。

補足日時:2011/08/23 12:26
    • good
    • 0

orで2つの条件を書く。



select a.id, b.名前
from Aテーブル a
inner join Bテーブル b on (
(b.番号1 = a.番号1 and b.番号2 = a.番号2)
or
(a.番号1 is null and b.番号2 = a.番号2)
);

もしくは、Aテーブルの番号1がnullのときはBテーブルの番号1で結合する(=全件ヒット)。

select a.id, b.名前
from Aテーブル a
inner join Bテーブル b on (
b.番号1 = nvl(a.番号1,b.番号1) and b.番号2 = a.番号2
);

でどうでしょうか。
    • good
    • 0

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

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

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

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

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

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

Q特定条件でWHERE句の条件を変更したい

@jouken int
@sql varchar(MAX)
@select varchar(MAX)
@where varchar(MAX)

set @select = 'select * from table1'
set @where = '
where
case
when @jouken = 0 then 'field1 = 1'
when @jouken = 1 then 'field1 = 1 or field2 = 1'
when @jouken = 2 then 'field1 = 1 or field2 = 1 or field3 = 1'
end
'
set @sql=@select+@where
exec(@sql)

上記のような文字列の組み合わせでの作成でやりたいことはできたのですが、
こちらを直接SQLの中でやりたいのです。
以下の文は機能しません。

select * from table1
where
case
when @jouken = 0 then field1 = 1
when @jouken = 1 then field1 = 1 or field2 = 1
when @jouken = 2 then field1 = 1 or field2 = 1 or field3 = 1
end

ご教授の程、よろしくお願い致します

@jouken int
@sql varchar(MAX)
@select varchar(MAX)
@where varchar(MAX)

set @select = 'select * from table1'
set @where = '
where
case
when @jouken = 0 then 'field1 = 1'
when @jouken = 1 then 'field1 = 1 or field2 = 1'
when @jouken = 2 then 'field1 = 1 or field2 = 1 or field3 = 1'
end
'
set @sql=@select+@where
exec(@sql)

上記のような文字列の組み合わせでの作成でやりたいことはできたのですが、
こちらを直接SQLの中でやりたいのです。
以下の文は機能しま...続きを読む

Aベストアンサー

andとorで記述できます。

select * from table1
where
@jouken = 0 and field1 = 1
or @jouken = 1 and (field1 = 1 or field2 = 1)
or @jouken = 2 and (field1 = 1 or field2 = 1 or field3 = 1)

QFROM の中で CASE を使えるでしょうか

http://msdn.microsoft.com/ja-jp/library/ms181765.aspx
…などを見ますと、どうもできそうに無いと思いますが、質問させて頂きます。
例えば、
SELECT *
FROM (CASE WHEN @FLG=0 THEN t当月集計 ELSE t累積集計 END) AS t請求残
…のように、FROMの中でCASEが使えると便利なときがあります。
エラーが出ますが、このような書き方はできないのでしょうか。

Aベストアンサー

CASE式でテーブルを切り替えることのできるDBMSはないと思います。
そのためにOracleでもSQL Serverでも苦労して動的クエリを書くのです。

SET @sql='SELECT * FROM '+CASE WHEN @FLG=0 THEN 't当月集計' ELSE 't累積集計' END+' AS t請求残'
EXEC (@sql)

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.年月 = 任意の値

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

Q引数によってwhere句を切り替える方法

PL/SQLで開発しています。
一つのテーブルで検索条件(引数)によって検索するカラムを切り替えたいのですが、
カーソルをいくつも作らず、
一つのSELECT文で書く方法ってないのでしょうか?
OR条件などを使って考えたのですが、うまくいきません。。

(例)
SELECT *
FROM 売り上げ情報
WHERE (品番 = 引数1 OR 商品名 = 引数2)

引数が無い時は"引数1"・"引数2"がNULLになるので、
カラムがPKなどになっていれば引数が片方しかなくてもうまく動作するのですが、
制限などがかかっていなくNULLで登録されているデータが存在すると余計なデータまでとれてしまいます。
DECODEなどでカラムに存在しない値に変換しようかとも思ったのですが、
なんか不自然な気が@@;
いい方法があれば教えてください。

Aベストアンサー

※ 前の投稿は不完全な状態でした。

「NULLで登録されているデータが存在すると余計なデータまでとれてしまいます」
と言っていますが「引数が無い場合、NULLデータが抽出から漏れる」という事では
ないでしょうか?
where句でNULLデータは「is null」でないと真になりません。

【対応策】
where 引数1 is null
    or (引数1 is not null and 品番 = 引数1)
   or
   引数2 is null
    or (引数2 is not null and 商品名 = 引数2)

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さんの発想はこれですよね。

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.区分

QSELECTで1件のみ取得するには?

こんにちわ。
いまORACLE9iを使用している者です。

ACCESSでは
SELECT TOP 1 項目名 FROM テーブル名
ORDER BY 項目名;
で並べ替えたデータ群のうち,先頭の1件だけを
取ることができますが,
ORACLEでそのような機能(SQL)はあるでしょうか?
教えてください。
よろしくお願いします。

Aベストアンサー

order by と rownum を併用する場合は注意が必要です。

[tbl01]
cola | colb
------------
1000 | aaaa
1001 | bbbb

というデータがある場合、
select cola from tbl01 where rownum < 1 order by cola desc;
とすると、「1001」ではなく、「1000」が返されます。
これは、order by の前に rownum < 1 が適用されてしまうからです。

解決するには、
select aaa from (select cola aaa from tbl01 order by cola desc) where rownum = 1;
とすれば良いです。

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')

と書くべきでしょうね。

QSQLで特定の項目の重複のみを排除した全項目を取得する方法

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のような構造になっている場合に「項目名1」について重複している項目を排除し、結果として


項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 B    え    イ    江

上のようなデータを取得したいのです。
この時に、Aの重複を排除して取得するレコードは1~3行目のどれでもよいです。
また、データを取得する際には必ずそのレコードの「全項目」を取得したいのでDistinctはうまく使えませんでした。

どなたか詳しい方、方法を教えてくださると幸いです。回答お待ちしております。

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のよ...続きを読む

Aベストアンサー

比較可能で一意性のある値をもてる項目6をテーブルに追加して、

select T.* from T, (select Item1,min(Item6) as Item6 from T group by item1) W where T.item6=W.item6;

――ってやるのが、一番手っ取り早いと思います。
他のところに影響がでないのであればですが。
oracleならrowidを使うとか、レコードの更新時刻を突っ込むとか。

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&Aを見た人がよく見るQ&A

人気Q&Aランキング