【问题标题】:How do I perform a simple one-statement SQL search across tables?如何跨表执行简单的单语句 SQL 搜索?
【发布时间】:2010-09-08 13:15:11
【问题描述】:

假设存在两个表:usersgroups

如何提供“简单搜索”,其中用户输入文本并且结果包含名称中包含该文本的用户和组?

搜索结果必须区分这两种类型。

【问题讨论】:

    标签: sql search


    【解决方案1】:

    诀窍是将UNION 与文字字符串组合以确定返回的“对象”的类型。在大多数(?)情况下,UNION ALL 会更有效,除非子查询中需要重复,否则应该使用 UNION ALL。以下模式就足够了:

     SELECT "group" type, name
       FROM groups
      WHERE name LIKE "%$text%"
    UNION ALL
     SELECT "user" type, name
       FROM users
      WHERE name LIKE "%$text%"
    

    注意:我自己添加了答案,因为我昨天遇到了这个问题,找不到好的解决方案,并使用了这种方法。如果有人有更好的方法,请随时添加。

    【讨论】:

      【解决方案2】:

      如果您使用“UNION ALL”,则数据库不会尝试删除重复项 - 无论如何,两个查询之间不会有重复项(因为第一列不同),因此 UNION ALL 会更快。
      (我假设您在要删除的每个查询中没有重复项)

      【讨论】:

      • 谢谢。产生相同的结果,虽然我还没有测试效率(还),但你说的很有意义。实际上,我也在选择一个主键。
      【解决方案3】:

      使用 LIKE 会导致许多问题,因为当 LIKE 比较器以 % 开头时,每次都需要进行一次表扫描。这会强制 SQL 检查每一行,并通过您用于比较的字符串逐字节地工作。虽然这在您开始时可能没问题,但很快就会导致扩展问题。

      处理此问题的更好方法是使用全文搜索。虽然这将是一个更复杂的选项,但它会为非常大的数据库提供更好的结果。然后,您可以使用 Bobby Jack 提供给您的示例的功能版本UNION ALL 将您的两个结果集放在一起并显示结果。

      【讨论】:

      • 当然,通过“简单”我想我也暗示(或试图!)这些都是非常小的表,并且应用程序的使用率很低,以至于蛮力的 LIKE 搜索完全可以接受。当活动放缓时,我将编辑问题以澄清这一点和其他点。干杯。
      【解决方案4】:

      我建议再添加一个

       SELECT "group" type, name
         FROM groups
        WHERE UPPER(name) LIKE UPPER("%$text%")
      UNION ALL
       SELECT "user" type, name
         FROM users
        WHERE UPPER(name) LIKE UPPER("%$text%")
      

      您可以先将 $text 转换为大写,或者直接在查询中进行。这样您就可以进行不区分大小写的搜索。

      【讨论】:

      • LIKE 的大小写敏感性取决于数据库(甚至可能是排序规则)。我正在使用 MySQL,其中 LIKE 比较无论如何都不区分大小写。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-10
      • 1970-01-01
      相关资源
      最近更新 更多