2009-07-19 2 views
3

다음 작업을 수행하려고합니다. 이 필드 (ID, 내용)가 포함 된 테이블이 있다고 가정 해 봅시다.MySQL, 적어도 X 문자가 일치하는 레코드를 선택하십시오.

1 | 사과

2 | 파인애플

3 | 응용 프로그램

4 | 국가 번호

지금 가능한 모든 공통 검색을 알려주는 기능을 찾고 있습니다. 예를 들어, 인수가 "3"이면이 함수는 하나 이상의 레코드에 나타나는 3 자의 가능한 모든 문자열을 반환합니다. "APPL을 :이 경우

, 내가 인수가"4 "인 경우, 내가 얻을"응용 프로그램 ","PPL ","PLE ","ATI ","TIO ","이온 "

를 얻을 수 ","pple ","페이지에 계속이 ","기 "가, 내가 얻을 :"5 "를 arugment이

이"ATION "

인수가" ","사과 (6)는 "nohting가 반환된다 .

지금까지는이를 수행하는 기능을 찾지 못했습니다.

Thx!

몇 가지 추가 정보 : 나는 이것을 MySQL 데이터베이스가있는 PHP 스크립트에서 사용하고 있습니다. 나는 단지 인자로서의 문자의 양과 물론 검색 할 테이블을주고 싶습니다.

+0

길이를 나타내는 숫자 외에도 쿼리에 대한 인수로 무엇을 보내시겠습니까? 이것이 어떤 언어를 기반으로 할 것입니까? –

답변

0

명백한 옵션은 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() 

쿼리의 모양을 생성 : 여기 파이썬에서 예입니다

[(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로 반복해야합니다. 실제로는 불가능합니다. 실제로 생성 된 SQL 쿼리가 미친 것처럼 보이고 필드 길이에 따라 다르다는 것을 제외하고는 그렉의 대답을 좋아합니다. –

관련 문제