SQLで'ABC'をDBの'AB'にHITする方法
- 現在、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以上の一番小さい数のデータを取得するという方法しか思いつかないのですが。 何か良い方法はありますでしょうか?
- sting2011
- お礼率100% (9/9)
- その他(データベース)
- 回答数5
- ありがとう数16
- みんなの回答 (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させたい ということです。
関連する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は使い方がよくわからないためシンタックスエラーにしかならず...。 そもそも、縦に結合?はできるのでしょうか??? あれこれ試してみたのですが、詰まってしまったので、 どなたか知恵をお貸しください。
- ベストアンサー
- PostgreSQL
- 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 Server
- 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では上手く行きませんでした。 よろしくお願いします。
- ベストアンサー
- Oracle
- 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' --> 駄目
- ベストアンサー
- SQL Server
- 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とかにしなくてはいけない日が来ると思うのです。 なんででしょう? 環境の問題とかでしょうか? 何か分かる方がいたら、よろしくお願いします。
- ベストアンサー
- Oracle
- 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とかにしなくてはいけない日が来ると思うのです。 なんででしょう? 環境の問題とかでしょうか? 何か分かる方がいたら、よろしくお願いします。
- ベストアンサー
- C・C++・C#
お礼
ありがとうございました。SQL側に手段が無さそうなのでC++で普通に書きます。
補足
なかなか説明不足ですいません。 あと返事が遅れて申し訳ありません。 上記の方にも書きましたが、 「ある製品の型番ABC000-00で ABC000の部分共通の情報がDBに入れてあり、 後ろの端数-00が-01になってもDBの情報は共通のまま使える という状況を想定しています。 なので新たにABC000-01とかABC000-0Bとかの型番が入ってきたら ABC000の情報をHITさせて出したいのです。」 という状況です。 あまりDBに慣れてないもので こういった場合って結構あるんじゃないかと思ったので 私の知らない素晴らしい方法が無いかとお尋ねした次第です。 (現在半分諦めて、全型番のDBを作り、そのテーブルを介して共通情報をリンクする案を模索しています) >と、少ない方から実行すれば、全部実行する必要が無い場合があります。 おお!確かにおっしゃる通りですね。 ありがとうございます。 >・先頭から一文字ずつ比較し、連続で一致する文字数を求める >・上記の「一致数」の最も多いものを抽出する >というのがルールなら「先頭から一文字ずつ比較し、連続で一致する文字数を求める」関数を作って、MAXの行を抽出する、という方法があります。 この辺は、やはりSQLでは用意されてはいないんですよね?