SQLで'ABC'をDBの'AB'にHITする方法

このQ&Aのポイント
  • 現在、sqlite3をVC++2013で使用している状況です。
  • 'ABC'という文字列をDBの'AB'にHITさせる方法を探しています。
  • 現在はキーを一文字ずつ増やして検索して最小のrow数を持つデータを取得していますが、他に良い方法はあるでしょうか?
回答を見る
  • ベストアンサー

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以上の一番小さい数のデータを取得するという方法しか思いつかないのですが。 何か良い方法はありますでしょうか?

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

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

sting2011
質問者

お礼

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

sting2011
質問者

補足

なかなか説明不足ですいません。 あと返事が遅れて申し訳ありません。 上記の方にも書きましたが、 「ある製品の型番ABC000-00で ABC000の部分共通の情報がDBに入れてあり、 後ろの端数-00が-01になってもDBの情報は共通のまま使える という状況を想定しています。 なので新たにABC000-01とかABC000-0Bとかの型番が入ってきたら ABC000の情報をHITさせて出したいのです。」 という状況です。 あまりDBに慣れてないもので こういった場合って結構あるんじゃないかと思ったので 私の知らない素晴らしい方法が無いかとお尋ねした次第です。 (現在半分諦めて、全型番のDBを作り、そのテーブルを介して共通情報をリンクする案を模索しています) >と、少ない方から実行すれば、全部実行する必要が無い場合があります。 おお!確かにおっしゃる通りですね。 ありがとうございます。 >・先頭から一文字ずつ比較し、連続で一致する文字数を求める >・上記の「一致数」の最も多いものを抽出する >というのがルールなら「先頭から一文字ずつ比較し、連続で一致する文字数を求める」関数を作って、MAXの行を抽出する、という方法があります。 この辺は、やはりSQLでは用意されてはいないんですよね?

その他の回答 (4)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.5

型番-枝番 という形式が固定されているなら、  instrで - を探す→ - みつかったら以降を削除(substr) 型番の桁が決まっているなら  substr(キー,型番の桁数) 等が考えられます。 また、「キー」列を「型番」「枝番」に分けたテーブルにして、使用時に必要なら 「型番」|| '-' || 「枝番」 みたいに連結する、とか。

sting2011
質問者

お礼

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

sting2011
質問者

補足

回答ありがとうございます。 ただ、「-」が省かれたりするんですよね。

回答No.3

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

sting2011
質問者

お礼

ありがとうございます。

sting2011
質問者

補足

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

回答No.2

select * from テーブル where キー like 'A%'; select * from テーブル where キー like 'AB%'; select * from テーブル where キー like 'ABC%'; 例を見ると文字列は自由に調整できるみたいですが... ズバリlike 'AB'にはできないの?

sting2011
質問者

お礼

ありがとうございます。

sting2011
質問者

補足

あるモジュール(DBからデータを抽出する)に渡す引数が’ABC’で DB内にキーが’AB’のrowが入っている。 ’ABC’内に’AB’が入っているのでこれを合致したと判断して’AB’のrowデータを 返したい。 Likeや%を使うと引数の文字数が少ない場合はそのまま使えますが 引数の文字数が多く、それでもHITさせたい場合どうしたものかと考えて 引数の文字を左から順番に増やしてselect文を掛けるを繰り返して 正解を導き出そうとしてこうなっています。

回答No.1

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

sting2011
質問者

お礼

ありがとうございます。

sting2011
質問者

補足

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

関連するQ&A

  • SQL 表の結合

    SQLで2つの表から条件に合ったデータを取り出し、同じ列に表示させたいのですが、 どうやっても外部結合のようにすることしかできませんでした。 取り出したデータを縦に結合?させることはできるのでしょうか? 例) dataは月の上旬中旬下旬でそれぞれabcとします。 入力値はmonthとdayで、これらからuriageを選択します。 dataの取りうる値はa,b,c,ab,bc,abcとします。    table:A 売上表            table:B 上旬中旬下旬判断 ---------------------------   -----------  key | data | month | uriage   day | data ---------------------------    -----------   1 |  a  |  1  |  500      1 |  a   2 |  ab  |  1  |  800     … |  …   3 |  bc  |  1  |  400     10 |  a   4 |  c  |  1  |  100     11 |  b   5 |  abc |  1  |  900     … |  …   … |  …  |  …  | …     31 |  c ---------------------------    ----------- month = 1 , day =5のとき  table:Bより   SELECT data FROM table:B WHERE day = 5 としてdata "a" を得ます。 この"a"と同じdataを持つuriageを表示させたいので   SELECT uriage FROM table:A   WHERE month = 1 AND data = (SELECT data FROM table:B WHERE day = 5) として  table:query1  --------    uriage  --------    500  -------- を得ました。 ここまでは良いのですが、これに付け加えて、 table:Bから取り出したdata "a"をtable:Aのdataが含むとき(data = a,ab,abcのとき) その全てのuriageを表示させたく、 ワイルドカードを使おうと   SELECT uriage FROM table:A   WHERE month = 1 AND data = %(SELECT data FROM table:B WHERE day = 5)% 等としてみたのですが、上手くいきませんでした。 そこで、別のクエリーを作って   SELECT uriage FROM table:A   WHERE month = 1 AND data = 'ab' AND data = 'abc' として  table:query2  ---------   uriage  ---------    800  ---------    900  ---------- を得ました。 そして、最後に、 得られた2つの表をまとめて  ---------   uriage  ---------    500  ---------    800  ---------    900  --------- としたいのですが、   SELECT uriage, uriage FROM query1, query2 とすると  ------------------   uriage | uriage  ------------------    500  |  800    500  |  900  ------------------ となりますし、UNIONは使い方がよくわからないためシンタックスエラーにしかならず...。 そもそも、縦に結合?はできるのでしょうか??? あれこれ試してみたのですが、詰まってしまったので、 どなたか知恵をお貸しください。

  • SQL キーワード検索にて

    お世話になります。 DBからSQLでキーワードによる検索をかけるときですが、 二つ以上のワードがあるときに、一つのキーワードがほかのキーワードと かぶってしまう場合、例えば゛、『あいうえお』と『いうえ』等で絞り込むと、 結果的に『あいうえお』が含まれるものだけが該当しますが、これを、 『あいうえお』を含み、更にそれ以外にも『いうえ』が含まれるものを 絞り込むには、どうすればよいでしょうか。 つまり、『あいうえお』のみしか含まれないものは該当しないようにする方法です。 現在のSQLは、 (SELECT * FROM xxxx WHERE tablename LIKE '%あいうえお%' AND tablename LIKE '%いうえ%') のような感じです。 使用しているDBは、MySQL、SQLiteです。 何卒よろしくお願いいたします。

  • 【至急】SQLの結合について教えてください。

    select * from A where ab = '1' and cd = '2' select ef from B where ab = '1' and cd = '2' and ef = '3' 至急質問させてください。 上記SQLを結合したいです。(Oracleです) 取得したいデータはAのテーブルの全項目で、 取得条件として、Bのテーブルの項目ef = '3' だったらという条件を加えたいです。 キー項目は両テーブルとも同じ(ab, cd)です。 どのようなSQLがスマートでしょうか。。 無知で申し訳ございませんが、ご教授いただけますと幸いです。 よろしくお願いいたします。

  • sqlのwhereで指定した条件の前後を取得したい

    テーブル=T) KEY DATA 001 あ 002 い 003 う 004 え 005 お SQL) SELECT DATA FROM T WHERE KEY = 003 ; 上記のSQLでは、「う」のデータしか取得できませんが、 「003」の前後1件、合計3件の「い」「う」「え」を取得する方法を教えて下さい。 ちなみに、 SELECT DATA FROM T WHERE KEY >= 003 AND ROWNUM <= 2 と SELECT * FROM ( SELECT DATA FROM T WHERE KEY < 003 ORDER BY KEY DESC ) WHERE ROWNUM < 1 のUNIONでは上手く行きませんでした。 よろしくお願いします。

  • LIKE検索の場合うまくいきません

    WEBアプリとSQLServerでSELECTをするときに不正をされないように SELECT * FROM DB WHERE DB.A = 検索文字 を SELECT * FROM DB WHERE DB.A= @A のようにして、@Aを後で指定しますが、 SELECT * FROM DB WHERE LIKE '%検索文字' のようにLIKE検索の場合うまくいきません。 どのように記述したらいいのでしょうか? SELECT * FROM DB WHERE DB.A LIKE @A --> 駄目 SELECT * FROM DB WHERE DB.A LIKE '%@A' --> 駄目

  • MSアクセス2013のSQLでESCAPE文字指定

    MSアクセス2013のSQLでLIKE検索時のエスケープ文字を別の文字に変更する ESCAPEキーワードを記述したら『演算子がありません』とエラーになったのですが 使えないんですか? select * from テーブル where 項目 like 'abc' ESCAPE '#' ;

  • DB2のSQL

    select * from xTABLE where EMP_ID = "P001" というSQLを実行すると SQL0206N "P001" is not valid in the context where it is used. SQLSTATE=42703 のエラーが出ます。 SQLSTATEで調べても「"P001"の列がテーブルにない」ということみたいですが 列名で捉えている時点でおかしい気がします select * from xTABLE where EMP_ID = null のSQLは正常にテーブルのSELECT結果が返ってきます。 どうすればよいでしょうか?

  • 【再投稿】Pro*Cの大文字小文字

    こんにちは。 現在Oracle9 Pro*Cで開発をしているのですが、下記のSQLが変です。 どう変かというと・・・ (1)EXEC SQL SELECT ABC FROM DB1 WHERE A_NUM = \'1\'; (2)EXEC SQL SELECT abc FROM DB1 WHERE A_NUM = \'1\'; (3)EXEC SQL SELECT Abc FROM DB1 WHERE A_NUM = \'1\'; 元々(1)のように記述してありました。 それがある日突然データがあるのにNotFoundになって、ためしに項目名ABCをabcに変えたところ、なぜだかselectできるようになりました。 しかし(2)も今日突然データがあるのにNotFoundになり、(3)のようにAbcにかえたところ、selectできるようになりました。 大文字小文字は関係ないと誰に聞いても言われるのですが、実際今は(3)でないと同じデータでもselectできません。 今はこれでいいですが、この調子で行くときっといつか(3)でもselectできなくなり、aBcとかにしなくてはいけない日が来ると思うのです。 なんででしょう? 環境の問題とかでしょうか? 何か分かる方がいたら、よろしくお願いします。

  • SQL : たしかに DELETE したの?

    ありがちな処理かと思いまして質問させていただきます。 SQLで DELETE を行う際、WHERE で絞り込んだ対象行がなくても、  「エラーは返ってこない」 ということですが、NOT FOUND判定はするのでしょうか。 ごく単純に、削除しようとしたデータが実際にあったのかを確認したいのです。 やろうとしている処理は、次のようなものです。 DELETE FROM a_tbl WHERE NOT EXISTS (SELECT row1 FROM b_tbl WHERE row1 = 'input_data' ) AND NOT EXISTS (SELECT row1 FROM c_tbl WHERE row1 = 'input_data' ); ようするに、他のテーブルに、すでにない行であることが前提で、 a_tbl から DELETE したことを確認したいのです。 Pro*C内で実行するのですが、一般に同じだと思います。 キホンのキかもしれませんが、よろしくお教えください。

  • Pro*Cの大文字小文字

    こんにちは。 現在Oracle9 Pro*Cで開発をしているのですが、下記のSQLが変です。 どう変かというと・・・ (1)EXEC SQL SELECT ABC FROM DB1 WHERE A_NUM = '1'; (2)EXEC SQL SELECT abc FROM DB1 WHERE A_NUM = '1'; (3)EXEC SQL SELECT Abc FROM DB1 WHERE A_NUM = '1'; 元々(1)のように記述してありました。 それがある日突然データがあるのにNotFoundになって、ためしに項目名ABCをabcに変えたところ、なぜだかselectできるようになりました。 しかし(2)も今日突然データがあるのにNotFoundになり、(3)のようにAbcにかえたところ、selectできるようになりました。 大文字小文字は関係ないと誰に聞いても言われるのですが、実際今は(3)でないと同じデータでもselectできません。 今はこれでいいですが、この調子で行くときっといつか(3)でもselectできなくなり、aBcとかにしなくてはいけない日が来ると思うのです。 なんででしょう? 環境の問題とかでしょうか? 何か分かる方がいたら、よろしくお願いします。