【问题标题】:How can I use LIKE with an arbitrary word order in MySQL?如何在 MySQL 中以任意词序使用 LIKE?
【发布时间】:2009-11-27 13:02:24
【问题描述】:

为此,我需要使用LIKE 关键字或其他类似的运算符:

在数据库中,姓名和姓氏被存储为一列,顺序为surname name(例如“Doe John”)。

我有一个搜索栏,可让您输入您的姓名和姓氏。当我要搜索时,我要求如果您输入 name surname 而不是 surname name(例如,如果您输入“John Doe”),我仍然希望显示与您编写 surname name 相同的结果。

我怎样才能做到这一点?

【问题讨论】:

  • 您想知道如何使用 LIKE 或如何将 (surname name) 交换为 (name surname)
  • 不,实际上我知道如何使用 LIKE。不过我一开始以为你可以用 LIKE 来做到这一点。因此,我想知道如何将姓氏交换为姓氏

标签: sql mysql


【解决方案1】:

如果您的表是MyISAM,您可以在两个字段上创建FULLTEXT 索引:

CREATE FULLTEXT INDEX ON mytable (name, surname)

并发出以下查询:

SELECT  *
FROM    mytable
WHERE   MATCH(name, surname) AGAINST ('+John +Doe' IN BOOLEAN MODE)

这将返回John DoeDoe John

MyISAM 表上,即使不创建索引,此查询也可以工作,但是,在这种情况下,它会慢得多。

更新:

即使您在单个字段中有姓名和姓氏,这也将起作用:

CREATE TABLE t_name (id INT NOT NULL PRIMARY KEY, name VARCHAR(200) NOT NULL) ENGINE=MyISAM;

INSERT
INTO    t_name
VALUES
(1, 'John Doe'),
(2, 'Doe John');

SELECT  *
FROM    t_name
WHERE   MATCH(name) AGAINST ('+John +Doe' IN BOOLEAN MODE);

1, 'John Doe'
2, 'Doe John'

更新 2:

InnoDB 表上,您可以使用正则表达式:

SELECT  *
FROM    t_name
WHERE   name RLIKE '[[:<:]]John[[:>:]]'
        AND name RLIKE '[[:<:]]Doe[[:>:]]'

【讨论】:

  • 我没有两个字段。我只有一个名为 Name 的字段,其中包含姓名和姓氏。那是我的问题...
  • 克里斯,这个 FULLTEXT 选项适用于您的一个 NAME 列,很好。如果您的某些名字中包含三个或更多单词,它也会起作用,例如“John Fitzgerald (Jack) Kennedy”
  • 好的,到时候试试这个。如果我成功了,会告诉你的。非常感谢!
【解决方案2】:

试试这个

原始数据:

姓名

Doe John
Stack Overflow
Pew Ned

记录搜索

declare @String2Search varchar(50)
set @String2Search = 'John Doe'

Sql 服务器查询

select name from @t 
where REPLACE(name,' ','') like '%' + REPLACE(@String2Search,' ','') + '%'
OR
SUBSTRING(name,CHARINDEX(' ',name),len(name)) + SUBSTRING(name,0,CHARINDEX(' ',name))  like '%' + REPLACE(@String2Search,' ','') + '%'

MySql 查询

select name from @t 
where REPLACE(name,' ','') like '%' + REPLACE(@String2Search,' ','') + '%'
OR 

SUBSTRING(name,LOCATE(' ',name),LENGTH(name)) + SUBSTRING(name,0,LOCATE(' ',name))  like '%' + REPLACE(@String2Search,' ','') + '%'

注意-我是一个 sql server 人。所以首先我在 SQL SERVER 中编写了查询,然后我在 google 中检查了 MYSQL 中的相应函数等价,我只是替换了那些

喜欢

SQLSERVER ---------------------------------------------- MYSQL



SUBSTRING() ------------Equivalent----------------------- SUBSTRING() 



CHARINDEX() ------------Equivalent----------------------- LOCATE()


REPLACE() --------------Equivalent----------------------- REPLACE()


LEN() --------------Equivalent----------------------- LENGTH()

在 Sql Server 中它工作正常。我实现的概念是我将搜索文本中的单词与名字和姓氏以及反向(姓氏和名字)进行匹配

我已经使用替换功能来删除字符之间的任何空格

这条语句(在sql server中)

SUBSTRING(name,CHARINDEX(' ',name),len(name)) + SUBSTRING(name,0,CHARINDEX(' ',name))

在我的 SQL 中

SUBSTRING(name,LOCATE(' ',name),LENGTH(name)) + SUBSTRING(name,0,LOCATE(' ',name)) 

基本上是将名字和姓氏转换为姓氏,然后是名字

希望您了解这个概念,它可能对您有所帮助。

【讨论】:

    【解决方案3】:

    试试这个:

    SELECT  *
    FROM    t_name
    WHERE   name LIKE '%john%' AND name LIKE '%doe%';
    

    【讨论】:

      【解决方案4】:
      //in PHP
      //after filtering and validating name and surname
      $where = 'WHERE name = ' .$name. ' ' .$surname. ' OR name = ' .$surname. ' ' .$name;
      

      检查两者。

      【讨论】:

      • 是的,我知道该解决方案,但由于某些原因,此时拆分名称会很复杂。请记住,名称是一个包含姓名和姓氏的属性。有没有办法直接从 SQL 中执行此操作?
      • @Chris:您将不得不在某些时候拆分名称。至少在这种情况下,只需将输入字符串拆分为空白字符即可。
      【解决方案5】:
      SELECT  SUBSTRING_INDEX(name, ' ', -1)
      SUBSTRING_INDEX(name, ' ', 1)
      

      作为计数的负值(第三个变量)返回空间右侧的所有内容。正值将所有内容返回到左侧。

      这是假设您有一个输入两个值的字段。

      【讨论】:

        【解决方案6】:

        您可以在空格处拆分搜索输入并分别搜索每个单词。您必须编写一个简单的函数来生成语句。基本上,如果您要搜索:

        Luke Skywalker
        

        你会得到的语句是:

        SELECT * FROM `table`
        WHERE
            (`name` LIKE "Luke%" OR `name` LIKE "Skywalker%")
            AND
            (`surname` LIKE "Luke%" OR `surname` LIKE "Skywalker%")
        

        如果有人搜索三个词(或仅一个词),您将在每个字段中有三个(或一个)LIKE 语句。如果您想不那么严格并且只需要匹配其中一个词,请将AND 替换为OR

        【讨论】:

          【解决方案7】:

          我不知道您使用的是什么语言,但上下文/主要思想应该保持不变。 您可以添加 2 个文本框,1 个用于姓名,1 个用于姓氏。 然后,您应该使用 LIKE 查询,按该顺序搜索您的文本框名称和姓氏值。

          编辑:

          第二种方法是拆分文本框的内容并将它们保存在 2 个单独的字符串中。 然后使用类似这样的方式搜索它:

          SELECT * FROM <your table> WHERE names LIKE 'name1+" "+name2' OR WHERE names LIKE 'name2+" "+name1';
          

          【讨论】:

          • 我不认为添加两个字段是一个用户友好的选项。 (可能在高级搜索页面上)
          • 是的,它可能总是另一种方法来检测是否有 2 个单词输入到文本框中,将它们拆分并在查询中使用 OR 在任一方向搜索它们。然后名称可能由 3 个甚至 4 个单词组成。
          • 有些名字包含2个名字和2个姓氏。你将如何拆分这样的名字?名称不一致。例如,您可能有一个名字 john w doe,或者您可能有另一个名字 john michael doe johns。如何拆分这些?
          【解决方案8】:
          SQL = "Select * From T_Name " & GetSuperWhere("Name", "John Smith")
          
          
          Private Function GetSuperWhere(FieldName As String, Words As String) As String
              Dim X() As String
              Dim Where As String = ""
              'sample: GetSuperWhere('Name', 'John Smith') -> Return: 
              '   " WHERE Name Like '%John%' AND Name Like '%Doe%'"
          
          
              X = Words.Split(" ")
              For Each Word As String In X
                  If Where <> "" Then Where = Where & " AND "
                  Where = Where & FieldName & " Like '%" & Word & "%'"
              Next
          
          
              If Where <> "" Then Where = " WHERE " & Where
          
          
              Return Where
          End Function
          

          【讨论】:

            猜你喜欢
            • 2012-03-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-10
            • 1970-01-01
            相关资源
            最近更新 更多