查询搜索所有可能的单词

时间:2016-03-24 23:46:05

标签: mysql sql delphi search

我需要编写一个Delphi 7和mysql数据库查询,它将返回包含提交名称中所有单词的记录。因此查询将返回具有所有这些名称单词但可以具有不同顺序的记录。

例如,如果搜索字符串是John Michael Smith,则查询应该能够返回名称为John Smith Michael,Michael Smith John,Smith John Michael或其他所有单词组合的记录。

可以看出,只返回在名称字段中仍然包含所有单词但可以具有不同顺序的记录。 我无法弄清楚如何为这样的要求编写查询。请帮忙。

procedure Tfrm_Query.Button1Click(Sender: TObject);
var
mask : string;
begin
  mask:='''%'+StringReplace(Edit1.text,' ','%',[rfReplaceAll, rfIgnoreCase])+'%''';
  if Edit1.Text > '' then
  begin
    Adosorgulama.Close;
    Adosorgulama.SQL.Clear;
    Adosorgulama.SQL.Add('SELECT * FROM stok.product');
    Adosorgulama.SQL.ADD('Where (P_Name like '+mask+')  limit 50');
    Adosorgulama.Open;
end;
end;

结果;

edit1.text:='Jo Mich'; // Result Ok!
edit1.text:='Smi Jo Mic'; //No result
edit1.text:='Mich Sm'; // No result

4 个答案:

答案 0 :(得分:0)

编写一个可以根据空格分割名称的函数。在循环拆分结果的循环中使用以下代码。

Declare @sqlq as nvarchar(max);

-- loop start
@sqlq = sqlq + 'Select * from mytable where names';

@sqlq = sqlq + 'like ''%' + loopvalue + '%''';
--loop end

Exec @sqlq

答案 1 :(得分:0)

您可以动态构建单词表。要找到你的匹配做查询,在可能的匹配中加入两个表,并通过分组结果测试它 - 名称包含所有单词,试试这个:

WITH 
  words AS (SELECT 'John' AS word FROM dual union 
      SELECT 'Michael' FROM dual union 
      SELECT 'Smith' FROM dual ) , --build your table of words (this is example on oracle DB engine)   
  names AS (SELECT 'John Michael Smith' AS name FROM dual UNION 
      SELECT 'John SmithMichael' FROM dual union 
      SELECT 'Smith Michael' FROM dual union 
      SELECT 'Smith Michael John' FROM dual union 
      SELECT 'John' FROM dual union 
      SELECT 'John John' FROM dual union 
      SELECT 'John John John' FROM dual union 
      SELECT 'xyz abc' FROM dual ) --this is simulation of yours table of names       
SELECT name, Count(DISTINCT word) 
FROM names, words
WHERE ' ' || name || ' ' LIKE '% ' || word || ' %'
GROUP BY name
HAVING Count(DISTINCT word) = (SELECT Count(1) FROM words)
;

答案 2 :(得分:0)

您可以将其替换为%

,而不是使用% AND P_Name LIKE %替换空格
mask:='''WHERE (P_Name LIKE %'+StringReplace(Edit1.text,' ','% AND P_Name LIKE %',[rfReplaceAll, rfIgnoreCase])+'%)''';

如果语法有问题(我不知道Delphi),请道歉,但如果Edit1.text:= 'John Michael Smith'这应生成以下WHERE子句:

WHERE (P_Name LIKE %John% AND P_Name LIKE %Michael% AND P_Name LIKE %Smith%)

哪个应该找到P_Name包含字符串'John','Michael'和'Smith'的所有记录。

然后,当然,而不是

Adosorgulama.SQL.ADD('Where (P_Name like '+mask+')  limit 50');

你会做类似

的事情
Adosorgulama.SQL.ADD(mask + '  limit 50');

如果输入可以包含无关的空格,则需要先删除它们,否则这将无效。

使用字符串连接形成SQL查询可能会使您的应用程序容易受到SQL注入攻击,因此您就知道了。我不知道如何用Delphi做预备语句,所以我无法帮助你。

答案 3 :(得分:0)

问题解决了。 Delphi + MySQL连接用word命令用以下代码,无论调用都可以。谢谢你的灵感。方面。

数据库模型;

CREATE TABLE IF NOT EXISTS `TableName` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `PNUMBER` varchar(20) DEFAULT NULL,
  `PNAME` varchar(255) DEFAULT NULL,
  `PBARCODE` varchar(30) DEFAULT NULL,
  `PSearch` mediumtext,
  PRIMARY KEY (`ID`),
  FULLTEXT KEY `PSearch` (`PSearch`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin5 ;

Psearch = PNUMBER + PNAME + PBARCODE ......; (键入所有区域PSearch)

Delphi7代码;

procedure TForm1.Button1Click(Sender: TObject);
var
mask : string;
begin
 mask:='+'+StringReplace(Edit1.text,' ','* +',[rfReplaceAll, rfIgnoreCase])+'*';
 if Edit1.Text > '' then
 begin
    Query1.Close;
    Query1.SQL.Clear;
    Query1.SQL.Add('SELECT MATCH(PSearch) AGAINST("'+mask+'" IN BOOLEAN MODE), tablename.* FROM database.tablename');
    Query1.SQL.Add('WHERE MATCH(PSearch) AGAINST("'+mask+'" IN BOOLEAN MODE) limit 300;');
    Query1.Open; 
    end; end;