- PR -

複数カラムによる範囲検索

投稿者投稿内容
るいるい
常連さん
会議室デビュー日: 2004/08/01
投稿数: 21
投稿日時: 2004-08-01 01:07
はじめまして。

愚問かもしれませんが、SQL構文でちょっと悩んでいます。
複数カラムによるデータ抽出をしたいのです。

例えば以下の様なデータがあったとします。

field1 field2
------- ----
X000002 A300
X000002 A301
X000003 A100
X000004 A200
X000004 A100
X000004 A200

このとき、
2レコード目[X000002 A301]から5レコード目[X000004 A100]までのデータを抽出したいのですが、このときどのようなSQL構文にすべきでしょうか。

以下のようなSQLのfield2の条件では当然データは抽出できません。

SELECT * FROM xx_data
WHERE
field1 >= 'X000002' field2 >='A301' AND
field1 <= 'X000004' field2 <='A101'

BETWEENを用いてもこれまた当然ながらNGです。

何かよい解決方法があれば、ご教授いただければ幸いです。
vincent
大ベテラン
会議室デビュー日: 2004/07/09
投稿数: 142
投稿日時: 2004-08-01 01:33
(パフォーマンス的な良し悪しはとりあえず置いといて)
field1とfield2の文字列を連結して比較すればよいと思います。
WHERE concat(field1,field2) BETWEEN 'X000002A301' AND 'X000004A100'
※ここではconcat(x, y)を
 xとyの文字列を連結した値を返すもの、とします

それが嫌なら
WHERE
(field1='X000002' AND field2>'A300')
OR
(field1 >'X000002' AND field1 < 'X000004')
OR
(field1='X000004' AND field2<='A100')

あとはサブクエリを使う方法とか、ですかねえ。
あんとれ
ぬし
会議室デビュー日: 2004/01/14
投稿数: 556
投稿日時: 2004-08-01 01:35
データがソートされているということでしたら、

(field1 > 'X000002' OR field1 = 'X000002' and field2 >='A301') AND
(field2 < 'X000004' OR field1 < 'X000004' and field2 <='A101')

という記述がもっともだと思います。

当然、field3 が存在すれば、もっと複雑な SQL 文になるのは言うまでもありません。
あんとれ
ぬし
会議室デビュー日: 2004/01/14
投稿数: 556
投稿日時: 2004-08-01 01:45
すみません。

2 行目、OR の後ろは

誤 field1 < 'X000004'
正 field1 = 'X000004'

でした。

でも、、、

> WHERE
> (field1='X000002' AND field2>'A300')
> OR
> (field1 >'X000002' AND field1 < 'X000004')
> OR
> (field1='X000004' AND field2<='A100')

確かにこんな表現もできますね。
こっちの方がすっきりしているかもしれません。
るいるい
常連さん
会議室デビュー日: 2004/08/01
投稿数: 21
投稿日時: 2004-08-01 02:05
vincent様 あんとれ様
早速のご返信ありがとうございます。
実は、私も結合すること考えたのですが、カラムが数値型だった場合や
パフォーマンスの事があり、挫折しました

でも、このSQLで何とかなりそうですね↓
> WHERE
> (field1='X000002' AND field2>'A300')
> OR
> (field1 >'X000002' AND field1 < 'X000004')
> OR
> (field1='X000004' AND field2<='A100')

でも、さらにカラム数の多い場合はかなり複雑なSQLになりそうですね。
やはり、スマートに抽出するのは無理なのかもしれないですね。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-08-02 09:26
はにまるです。

 DBMSがOracleで、コストベース運用をされている場合、
 ファンクション索引(ファンクション・ベース索引)を検討されると宜しいかと思います。
 
 適用可能であれば、vincentさん案でパフォーマンスが保持出来ると思います。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-08-02 10:13
unibon です。こんにちわ。

引用:

るいるいさんの書き込み (2004-08-01 02:05) より:
でも、さらにカラム数の多い場合はかなり複雑なSQLになりそうですね。
やはり、スマートに抽出するのは無理なのかもしれないですね。


複数のカラムに渡って位付け(位取り)を自前でおこなうことになるので、たしかにカラムの数が多くなると複雑になります。しかし、このような場合は任意のカラム数に対応できるような SQL を生成するサブルーチンを作ってやれば良いと思います。
#でもどう書けばよいのかは良く分からない。どこかにないですかね。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-08-02 10:50
はにまるです。

 ひとりごとです。

 「主番」と「枝番」を一つのキーと見なして範囲指定をする方法は
 シーケンシャル・アクセス(順次読み)方式のみ、またはその方が高速であった時代の
 「データ管理ツール」や「記憶媒体」を利用していた背景による
 苦肉の策の方式と考えます。

 RDB+HDD構成であれば、「主番」と「枝番」で範囲指定を
 個別にした方がユーザも喜ぶのでは、、、
 と、仕様も判らず勝手に想像してみる今日このごろ。

 # 「主番」の意味「枝番」の意味が明確で且つ
 # システム定義されていなければ意味ないけど。

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