【发布时间】:2010-09-08 13:15:11
【问题描述】:
假设存在两个表:users 和 groups。
如何提供“简单搜索”,其中用户输入文本并且结果包含名称中包含该文本的用户和组?
搜索结果必须区分这两种类型。
【问题讨论】:
假设存在两个表:users 和 groups。
如何提供“简单搜索”,其中用户输入文本并且结果包含名称中包含该文本的用户和组?
搜索结果必须区分这两种类型。
【问题讨论】:
诀窍是将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%"
注意:我自己添加了答案,因为我昨天遇到了这个问题,找不到好的解决方案,并使用了这种方法。如果有人有更好的方法,请随时添加。
【讨论】:
如果您使用“UNION ALL”,则数据库不会尝试删除重复项 - 无论如何,两个查询之间不会有重复项(因为第一列不同),因此 UNION ALL 会更快。
(我假设您在要删除的每个查询中没有重复项)
【讨论】:
使用 LIKE 会导致许多问题,因为当 LIKE 比较器以 % 开头时,每次都需要进行一次表扫描。这会强制 SQL 检查每一行,并通过您用于比较的字符串逐字节地工作。虽然这在您开始时可能没问题,但很快就会导致扩展问题。
处理此问题的更好方法是使用全文搜索。虽然这将是一个更复杂的选项,但它会为非常大的数据库提供更好的结果。然后,您可以使用 Bobby Jack 提供给您的示例的功能版本UNION ALL 将您的两个结果集放在一起并显示结果。
【讨论】:
我建议再添加一个
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 转换为大写,或者直接在查询中进行。这样您就可以进行不区分大小写的搜索。
【讨论】: