- ベストアンサー
SQLで'ABC'をDBの'AB'にHITする方法
- 現在、sqlite3をVC++2013で使用している状況です。
- 'ABC'という文字列をDBの'AB'にHITさせる方法を探しています。
- 現在はキーを一文字ずつ増やして検索して最小のrow数を持つデータを取得していますが、他に良い方法はあるでしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
すみません。 「ABC から、 AB を探す」 のルールがはっきりしません。 この1例だけ聞くと 「AB をヒットさせたいなら、 ABCから一文字削って AB にして、検索すればいい」 ってなります。でも、そうでは無いですね? 例えば。 キーに AB,ABC があったら、 ・ AB, ABC 両方にヒット ・ AB だけヒット ・ ABC だけヒット のどれなのでしょうか?その理由は? キーに AB,ABD があったら、 ・ AB, ABD 両方にヒット ・ AB だけヒット ・ ABD だけヒット のどれなのでしょうか?その理由は? キーに ABC,ABD があったら、 ・ ABC, ABD 両方にヒット ・ ABC だけヒット ・ ABD だけヒット のどれなのでしょうか?その理由は? キーに ABD,ABE があったら、 ・ ABD, ABE 両方にヒット ・ ABD だけヒット ・ ABE だけヒット ・どちらもヒットしない のどれなのでしょうか?その理由は? .... 等々。この「その理由」を整理して「一般的なルール」にすれば、他の方法も考えやすくなるでしょう。 > row数が0以上の一番小さい数のデータを取得 というのは R1 = 「select * from テーブル where キー like 'A%';」で抽出される件数 R2 = 「select * from テーブル where キー like 'AB%';」で抽出される件数 R3 = 「select * from テーブル where キー like 'ABC%';」で抽出される件数 の、0でない Rx が最小となる条件を選択する という意味でよろしいでしょうか? それだと R1≧R2≧R3 なのがあきらかなので select * from テーブル where キー like 'ABC%'; → ヒットしたら採用して終了 select * from テーブル where キー like 'AB%'; → ヒットしたら採用して終了 select * from テーブル where キー like 'A%'; → ヒットしたら採用、ヒットしなければ0件 と、少ない方から実行すれば、全部実行する必要が無い場合があります。 ・先頭から一文字ずつ比較し、連続で一致する文字数を求める ・上記の「一致数」の最も多いものを抽出する というのがルールなら「先頭から一文字ずつ比較し、連続で一致する文字数を求める」関数を作って、MAXの行を抽出する、という方法があります。
その他の回答 (4)
- kmee
- ベストアンサー率55% (1857/3366)
型番-枝番 という形式が固定されているなら、 instrで - を探す→ - みつかったら以降を削除(substr) 型番の桁が決まっているなら substr(キー,型番の桁数) 等が考えられます。 また、「キー」列を「型番」「枝番」に分けたテーブルにして、使用時に必要なら 「型番」|| '-' || 「枝番」 みたいに連結する、とか。
お礼
仰るとおり、C++で実現するしかなさそうですね。ありがとうございました。
補足
回答ありがとうございます。 ただ、「-」が省かれたりするんですよね。
- ggggggggggg hhhhhhhhhhh(@tasketeqq1)
- ベストアンサー率15% (36/231)
事情がよく分からないのですが、正規表現を使ってもダメなのですか?
お礼
ありがとうございます。
補足
ああ、ごめんなさい、返事が遅れました。 ある製品の型番ABC000-00で ABC000の部分共通の情報がDBに入れてあり、 後ろの端数-00が-01になってもDBの情報は共通のまま使える という状況を想定しています。 なので新たにABC000-01とかABC000-0Bとかの型番が入ってきたら ABC000の情報をHITさせて出したいのです。
- ggggggggggg hhhhhhhhhhh(@tasketeqq1)
- ベストアンサー率15% (36/231)
select * from テーブル where キー like 'A%'; select * from テーブル where キー like 'AB%'; select * from テーブル where キー like 'ABC%'; 例を見ると文字列は自由に調整できるみたいですが... ズバリlike 'AB'にはできないの?
お礼
ありがとうございます。
補足
あるモジュール(DBからデータを抽出する)に渡す引数が’ABC’で DB内にキーが’AB’のrowが入っている。 ’ABC’内に’AB’が入っているのでこれを合致したと判断して’AB’のrowデータを 返したい。 Likeや%を使うと引数の文字数が少ない場合はそのまま使えますが 引数の文字数が多く、それでもHITさせたい場合どうしたものかと考えて 引数の文字を左から順番に増やしてselect文を掛けるを繰り返して 正解を導き出そうとしてこうなっています。
- ggggggggggg hhhhhhhhhhh(@tasketeqq1)
- ベストアンサー率15% (36/231)
「DBに渡す文字が'ABC'・・」 意味がわかりませんが。
お礼
ありがとうございます。
補足
ああ、ごめんなさい。 select文で、’ABC’を渡して、DB内の’AB’のデータにHITさせたい ということです。
お礼
ありがとうございました。SQL側に手段が無さそうなのでC++で普通に書きます。
補足
なかなか説明不足ですいません。 あと返事が遅れて申し訳ありません。 上記の方にも書きましたが、 「ある製品の型番ABC000-00で ABC000の部分共通の情報がDBに入れてあり、 後ろの端数-00が-01になってもDBの情報は共通のまま使える という状況を想定しています。 なので新たにABC000-01とかABC000-0Bとかの型番が入ってきたら ABC000の情報をHITさせて出したいのです。」 という状況です。 あまりDBに慣れてないもので こういった場合って結構あるんじゃないかと思ったので 私の知らない素晴らしい方法が無いかとお尋ねした次第です。 (現在半分諦めて、全型番のDBを作り、そのテーブルを介して共通情報をリンクする案を模索しています) >と、少ない方から実行すれば、全部実行する必要が無い場合があります。 おお!確かにおっしゃる通りですね。 ありがとうございます。 >・先頭から一文字ずつ比較し、連続で一致する文字数を求める >・上記の「一致数」の最も多いものを抽出する >というのがルールなら「先頭から一文字ずつ比較し、連続で一致する文字数を求める」関数を作って、MAXの行を抽出する、という方法があります。 この辺は、やはりSQLでは用意されてはいないんですよね?