こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

SQLで'ABC'をDBの'AB'にHIT

sqlite3をVC++2013で扱っています。
もしかしたら、単純な方法があるのかもしれないので質問させてください。

DBに渡す文字が'ABC'でDB内のデータ'AB'にHITさせたいと思っています。

現状思いつく方法は

select * from テーブル where キー like 'A%';
select * from テーブル where キー like 'AB%';
select * from テーブル where キー like 'ABC%';

と渡す文字を一文字ずつ増やして検索して
row数が0以上の一番小さい数のデータを取得するという方法しか思いつかないのですが。

何か良い方法はありますでしょうか?

投稿日時 - 2014-12-05 11:30:05

QNo.8847865

すぐに回答ほしいです

質問者が選んだベストアンサー

すみません。
「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の行を抽出する、という方法があります。

投稿日時 - 2014-12-06 07:07:17

補足

なかなか説明不足ですいません。
あと返事が遅れて申し訳ありません。

上記の方にも書きましたが、
「ある製品の型番ABC000-00で
ABC000の部分共通の情報がDBに入れてあり、
後ろの端数-00が-01になってもDBの情報は共通のまま使える
という状況を想定しています。

なので新たにABC000-01とかABC000-0Bとかの型番が入ってきたら
ABC000の情報をHITさせて出したいのです。」
という状況です。

あまりDBに慣れてないもので
こういった場合って結構あるんじゃないかと思ったので
私の知らない素晴らしい方法が無いかとお尋ねした次第です。
(現在半分諦めて、全型番のDBを作り、そのテーブルを介して共通情報をリンクする案を模索しています)

>と、少ない方から実行すれば、全部実行する必要が無い場合があります。

おお!確かにおっしゃる通りですね。
ありがとうございます。

>・先頭から一文字ずつ比較し、連続で一致する文字数を求める
>・上記の「一致数」の最も多いものを抽出する
>というのがルールなら「先頭から一文字ずつ比較し、連続で一致する文字数を求める」関数を作って、MAXの行を抽出する、という方法があります。

この辺は、やはりSQLでは用意されてはいないんですよね?

投稿日時 - 2014-12-08 13:51:22

お礼

ありがとうございました。SQL側に手段が無さそうなのでC++で普通に書きます。

投稿日時 - 2014-12-16 11:55:26

ANo.4

このQ&Aは役に立ちましたか?

10人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(5)

ANo.5

型番-枝番
という形式が固定されているなら、
 instrで - を探す→ - みつかったら以降を削除(substr)
型番の桁が決まっているなら
 substr(キー,型番の桁数)
等が考えられます。

また、「キー」列を「型番」「枝番」に分けたテーブルにして、使用時に必要なら
「型番」|| '-' || 「枝番」
みたいに連結する、とか。

投稿日時 - 2014-12-13 08:15:21

補足

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

ただ、「-」が省かれたりするんですよね。

投稿日時 - 2014-12-16 11:49:17

お礼

仰るとおり、C++で実現するしかなさそうですね。ありがとうございました。

投稿日時 - 2014-12-16 11:55:34

ANo.3

事情がよく分からないのですが、正規表現を使ってもダメなのですか?

投稿日時 - 2014-12-05 17:39:12

補足

ああ、ごめんなさい、返事が遅れました。
ある製品の型番ABC000-00で
ABC000の部分共通の情報がDBに入れてあり、
後ろの端数-00が-01になってもDBの情報は共通のまま使える
という状況を想定しています。

なので新たにABC000-01とかABC000-0Bとかの型番が入ってきたら
ABC000の情報をHITさせて出したいのです。

投稿日時 - 2014-12-08 13:38:29

お礼

ありがとうございます。

投稿日時 - 2014-12-16 12:01:43

ANo.2

select * from テーブル where キー like 'A%';
select * from テーブル where キー like 'AB%';
select * from テーブル where キー like 'ABC%';

例を見ると文字列は自由に調整できるみたいですが...
ズバリlike 'AB'にはできないの?

投稿日時 - 2014-12-05 11:48:48

補足

あるモジュール(DBからデータを抽出する)に渡す引数が’ABC’で
DB内にキーが’AB’のrowが入っている。
’ABC’内に’AB’が入っているのでこれを合致したと判断して’AB’のrowデータを
返したい。

Likeや%を使うと引数の文字数が少ない場合はそのまま使えますが
引数の文字数が多く、それでもHITさせたい場合どうしたものかと考えて

引数の文字を左から順番に増やしてselect文を掛けるを繰り返して
正解を導き出そうとしてこうなっています。

投稿日時 - 2014-12-05 12:02:56

お礼

ありがとうございます。

投稿日時 - 2014-12-16 12:01:17

ANo.1

「DBに渡す文字が'ABC'・・」
意味がわかりませんが。

投稿日時 - 2014-12-05 11:33:27

補足

ああ、ごめんなさい。
select文で、’ABC’を渡して、DB内の’AB’のデータにHITさせたい
ということです。

投稿日時 - 2014-12-05 11:35:48

お礼

ありがとうございます。

投稿日時 - 2014-12-16 12:01:25

-広告-
-広告-
-広告-
-広告-