- PR -

SQLコマンドについて

1
投稿者投稿内容
未記入
会議室デビュー日: 2008/05/27
投稿数: 1
投稿日時: 2008-05-27 18:14
初めまして。佐々木と申します。
初心者の質問で申し訳ございませんが、
ご指導頂けるとありがたいです。

下記の3つのテーブルがあるとします。

Sample A
------------
|区別|ランク|
------------
| A |LV1 |
| B |LV2 |
| C |LV3 |
| D |LV4 |
| E |LV5 |
| F |LV10 |
------------


Sample B
--------------------
|No |名前 |区別 |
--------------------
|11 |一郎 |A |
|12 |二郎 |B |
|13 |三郎 |C |
|14 |四郎 |B |
|15 |五郎 |E |
--------------------


Sample C
-----------
|No |実績 |
-----------
|11 |90 |
|12 |80 |
|13 |110 |
|14 |90 |
|15 |220 |
-----------

この場合、下記のようなSQLを作りたいと思います。
 ・テーブル「Sample B」のカラム「区別」と、テーブル「Sample A」のカラム「区別」を
  紐付けてテーブル「Sample A」のカラム「ランク」を引っ張りだす。
 ・ただし、テーブル「Sample C」を参照しカラム「実績」が100以上の場合は無条件にランク「LV10」を引っ張り出す。

条件分岐がうまくできません。
どなたかご指導頂けますでしょうか。

以上、宜しくお願い致します。













かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2008-05-27 21:50
使用してるDBMSとバージョンは何?

表式とcase句が使えるのなら、
コード:
select
	V.No, V.名前, A.ランク
from (
	select B.No, B.名前, (case when C.実績 >= 100 then 'F' else C.実績 end) as 実績
	from B
	join C on B.No = C.No
) V
join A on V.実績 = A.実績


ってので、いけるかも。

でも未検証なので、自信なし。
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2008-05-27 22:05
以下、直接の回答ではないことをお断り申し上げておきます。

・初めての方のようなのでご存知なかったのかもしれませんが、SQL について質問される際は RDBMS に何を使用しているか、製品名とバージョンを書かれた方がよろしいと思います。
SQL92 や SQL99 といった標準仕様はありますが、製品によっては準拠が完全ではなかったり、また製品によっては特有の記法でより効率の良いクエリを書く方法があったりします。

・「条件分岐がうまくできません」とのことですが、ご自身がどのようなクエリを書いてどのような結果を得、それが期待した結果とどのように違うのかを明記されるのも良いと考えます。

例えば私が隣の席にいたり後から見ていた同僚であれば、何をしてどのような結果になったのかがわかり、適切なアドバイスを差し上げられるかもしれません。
けれども、ネット上の掲示板では書かれている情報がすべてです。
言い換えると、書かれていない情報を回答者が知る術はありません。

以上、より詳細な情報を記載されるようお願いいたします。

苦言だけではナンですので、ヒントのみ差し上げたいと思います。
(SQL92 仕様に基づいていますが、今手許に RDBMS がないので動作確認していません(_ _))

テーブル A
--------
|ID|VAL|
--------
| 1| 1|
| 2| 2|
--------

クエリ
SELECT ID, CASE WHEN VAL>=2 THEN 10 ELSE VAL END
FROM A
とんくま
ベテラン
会議室デビュー日: 2005/08/02
投稿数: 56
お住まい・勤務地: 東京
投稿日時: 2008-05-27 23:41
DB2 では、
コード:
SELECT B.*

, 実績
, ランク
FROM SampleB B
INNER JOIN
SampleC C
ON C.no = B.no
INNER JOIN
SampleA A
ON A.区別 = CASE WHEN 実績 > 100 THEN 'F' ELSE B.区別 END
;


あるいは、2番目の ON 条件を
コード:
   ON  実績 >  100 AND A.区別 = 'F'

OR 実績 <= 100 AND A.区別 = B.区別


で出来ますが
他の RDBMSで可能かはチェックしていません。




[ メッセージ編集済み 編集者: とんくま 編集日時 2008-05-27 23:42 ]
とんくま
ベテラン
会議室デビュー日: 2005/08/02
投稿数: 56
お住まい・勤務地: 東京
投稿日時: 2008-05-28 04:20
蛇足とは思いますが、私の思考過程を少し解説すると

コード:
   ON  実績 >  100 AND A.区別 = 'F'
   OR  実績 <= 100 AND A.区別 = B.区別
の導出過程:
 一般的に、a, b, c を述語とすると、
IF a THEN
   b
ELSE
   c
は、
(a AND b) OR ((NOT a) AND c)
と表せます。
SQL における(一般的にもだいたい同じでしょうが)論理演算子の優先順位(NOT > AND > OR)を考慮し 
具体的な述語、
a := 実績 >  100
b := A.区別 = 'F'
c := A.区別 = B.区別
と置き換えると、最初の条件が獲られます。

別の見方をすると、要求する条件は、
IF a THEN
    x = y
ELSE
    x = z
の形式になっているので、
x = (IF a THEN y ELSE z)
と置き換えられます。
ここで、a, x, y, z を具体的な条件(a)、変数(x, y, z)に置き換えると
A.区別 = (IF 実績 > 100 THEN 'F' ELSE z B.区別)
SQL の文法で書くと、
A.区別 = CASE WHEN 実績 > 100 THEN 'F' ELSE z B.区別 END
が、得られます。


以上の説明は、かなり感覚的で厳密さに欠けるでしょうが、普通に SQL 文を組み立てるには結構有効だと思います。
明智重蔵
大ベテラン
会議室デビュー日: 2005/09/05
投稿数: 127
投稿日時: 2008-05-28 06:59
Oracle10gで作ってみました。

コード:
select b.No,b.名前,b.区別,
case when c.実績 >= 100 then 'LV10' else a.ランク end as ランク
  from SampleA a,SampleB b,SampleC c
 where a.区別 = b.区別
   and b.No = c.No

とんくま
ベテラン
会議室デビュー日: 2005/08/02
投稿数: 56
お住まい・勤務地: 東京
投稿日時: 2008-05-28 17:06
> ・テーブル「Sample B」のカラム「区別」と、テーブル「Sample A」のカラム「区別」を
>  紐付けてテーブル「Sample A」のカラム「ランク」を引っ張りだす。

これは、一般的にコード→値の変換を
1)外部データとしての表を参照して行なうか、
2)プログラム(SQL文)内にハードコードするか、
の選択として捉えられるように思えます。

「区別」の数(テーブル「Sample A」の行数)、
「区別」の変更頻度、
対応する「ランク」値の変更頻度、
関連するSQL文・プログラムの数、
等が主な判断基準と成るでしょう。

> ・ただし、テーブル「Sample C」を参照しカラム「実績」が100以上の場合は無条件にランク「LV10」を引っ張り出す。

”ランク「LV10」”と指定しているので、明智重蔵さんの方法も有るとは思いますが、
”...を引っ張り出す”という表現にこだわると、私の方法も意味が有るかな(ランク値の変更(例えば、LVx → LVLx)が容易、等)と思います。

また、
SQL文内にランク「LV10」をコーディングするなら、
その他の「区別」についてもSQL文内にコーディングすれば、テーブル「Sample A」への参照は不要になります。
コード:
SELECT B.*

, 実績
, CASE
WHEN 実績 >= 100
OR 区別 = 'F' THEN 'LV10'
WHEN 区別 = 'A' THEN 'LV1'
WHEN 区別 = 'B' THEN 'LV2'
WHEN 区別 = 'C' THEN 'LV3'
WHEN 区別 = 'D' THEN 'LV4'
WHEN 区別 = 'E' THEN 'LV5'
END ランク
FROM SampleB B
INNER JOIN
SampleC C
ON C.no = B.no
;




[ メッセージ編集済み 編集者: とんくま 編集日時 2008-05-28 17:09 ]
1

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