2009-07-19 15 views
3

私は以下を達成しようとしています。これらのフィールド(ID、コンテンツ)を含む表があるとします。MySQL、少なくともX文字が一致するレコードを選択してください

1 |リンゴ

2 |パイナップル

3 |アプリケーション

4 |国

今、可能性のあるすべての共通一致を教えてくれる関数を探しています。たとえば、引数が "3"の場合、関数は複数のレコードに表示される3文字からすべての文字列を返します。この場合

、私は "アプリ"、 "PPL"、 "PLE"、 "ATI"、 "ョ"、 "イオン"

を取得する引数は "4" であれば、私が手:「APPLを」、 "pple"、 "atio"、 "ン"

arugmentがある場合は、 "5"、私が手: "りんご"、 "エーション6 ""

引数がある場合は"、nohtingが返されます。

これまでのところ、これを達成する関数は見つかりませんでした。

Thx!

いくつかの追加情報: 私はこれをMySQLデータベースのPHPスクリプトで使用しています。私は実際に文字の量を引数として与え、もちろん検索するテーブルを与えたいだけです。

+0

長さを表す数字の他に、クエリの引数として他に何を送信する予定ですか?これはどのコーディング言語に基づいていますか? –

答えて

0

明らかなオプションの1つはREGEXを使用することです。これまでの経験はありませんが、これはあなたの役に立つかもしれません。 http://dev.mysql.com/doc/refman/5.1/en/regexp.html

必要なものに合わせて適切な式を見つける必要があります。

+0

これはあまり明白ではありません。ランダムな正規表現を実行し、結果を表の他のすべてのレコードと照合することを意味します。私はそのための正規表現を含むSQLを見ることができません。 – PatrikAkerstrand

+0

上記のとおり、これはソリューションのほんの一部です。私は探す文字を知らない。 5文字で、ランダムにした場合、実行する必要がある2^5の正規表現クエリが得られます。残念ながら、これはこの問題には適していません。 – Digits

+0

@Machine私はそれを再読するまで完全に質問を理解していなかったと思う。同意すると、私の「明白な」オプションは結局適用されませんでした。私は本当にこれはSQLクエリのみを使用して達成できるとは思わないが、私は確かに間違っていることを証明したいと思います。 –

3

これは醜いですが、正常に動作します。それは一般的なSQLであり、どんな環境でも動作します。あなたが読んでいるフィールドの最大長より長い部分文字列の選択肢をいくつか生成するだけです。関数内の数値50をフィールド長を超える数値に変更します。それはrealllly長いクエリを返すかもしれませんが、私が言ったように、それは正常に動作します。

select substr FROM 
    (select substr(content,0,3) AS substr, count(*) AS myCount from myTable where length(substr(content,0,3))=3 group by substr(content,0,3) 
    union all select substr(content,1,3) AS substr, count(*) AS myCount from myTable where length(substr(content,1,3))=3 group by substr(content,1,3) 
    union all select substr(content,2,3) AS substr, count(*) AS myCount from myTable where length(substr(content,2,3))=3 group by substr(content,2,3) 
    union all select substr(content,3,3) AS substr, count(*) AS myCount from myTable where length(substr(content,3,3))=3 group by substr(content,3,3) 
    union all select substr(content,4,3) AS substr, count(*) AS myCount from myTable where length(substr(content,4,3))=3 group by substr(content,4,3) 
    ...) 
GROUP BY substr HAVING sum(myCount) > 1 

そして、作成された結果は次のとおりです:

import sqlite3 

c = sqlite3.connect('test.db') 

c.execute('create table myTable (id integer, content varchar[50])') 
for id, content in ((1,'apple'),(2,'pineapple'),(3,'application'),(4,'nation')): 
    c.execute('insert into myTable values (?,?)', [id,content]) 

c.commit(); 

def GenerateSQL(substrSize): 
    subqueries = ["select substr(content,%i,%i) AS substr, count(*) AS myCount from myTable where length(substr(content,%i,%i))=%i group by substr(content,%i,%i) " % (i,substrSize,i,substrSize,substrSize,i,substrSize) for i in range(50)] 
    sql = 'select substr FROM \n\t(' + '\n\tunion all '.join(subqueries) + ') \nGROUP BY substr HAVING sum(myCount) > 1' 
    return sql 

print GenerateSQL(3) 

print c.execute(GenerateSQL(3)).fetchall() 

クエリのようなルックスを生成:ここではPythonで例がある

[(u'app',), (u'ati',), (u'ion',), (u'nat',), (u'pin',), (u'ple',), (u'ppl',), (u'tio',)] 
+0

私はこれを試して、私のサーバが爆発するかどうかを知らせます;)Thx – Digits

2

私が持っていないようごめんなさいしばらくの間、PHPで遊んでいた&私はそれのための適切なテスト環境がありませんが、私はすぐにC#3.5でこれを行う方法を考案しました

疑似コード:指定された長さの文字列を持つテーブルを作成します。&横に発生数がカウントされます。数> 1を選択:

static void Main(string[] args) 
    { 

     string[] data = { "apple", "pinapple", "application", "nation" }; 
     string[] result = my_func(3,data); 

     foreach (string str in result) 
     { 
      Console.WriteLine(str); 
     } 
     Console.ReadKey(); 
    } 

    private static string[] my_func(int l, string[] data) 
    { 
     Dictionary<string,int> dict = new Dictionary<string,int>(); 
     foreach (string str in data) 
     { 
      for (int i = 0; i < str.Length - l + 1; i++) 
      { 
       string part = str.Substring(i, l); 
       if (dict.ContainsKey(part)) 
       { 
        dict[part]++; 
       }else { 
        dict.Add(part,1); 
       } 
      } 
     } 
     var result = from k in dict.Keys 
       where dict[k] > 1 
       orderby dict[k] descending 
       select k; 

     return result.ToArray<string>(); 
    } 
+0

これは面白そうです。私はあなたの辞書にすべての "クイックコール"、私の場合はSQLクエリになるので、パフォーマンスについてちょっと心配です。また、10kレコードのテーブルをキャッシュすることも良い考えではないかもしれませんが、私はそれをチェックします! – Digits

+0

あなたはそうです、このコードはサーバ上で動くべきです、そして、それはSQLで書かれる必要があるようですが、あなたはSQLで反復する必要があります。実際にGregの答えが好きなのは、生成されたSQLクエリが狂っているように見えて、フィールド長に依存するという点です。 –

関連する問題