我正在处理查询以搜索特定表格。要求说我需要获取所有记录,其中任何一组字段都是like
输入值。因此,我有一个类似于
SELECT * FROM MyTable
WHERE Col1 like @input
or Col2 like @input
or Col3 like @input
where子句中可以有任意数量的列。一个特定的客户将有50列。因此,这个where子句将变得相当昂贵。
是否可以使用其他语法或方法,以便我可以说“输入值是否存在于任何x列中?”
您会以不同的方式编写查询吗?
答案 0 :(得分:3)
根据允许通配符的位置和位置,这些查询的确可能非常昂贵,因为优化器在使用其中许多查询时会遇到问题,无法加快它们的速度。
如果您在MS SQL Server上运行此功能,可以考虑使用全文搜索功能和CONTAINS关键字来实现此功能。
SELECT *
FROM MyTable
WHERE CONTAINS
((col1,col2,col3) ,@input)
或搜索所有文本索引列
SELECT *
FROM MyTable
WHERE CONTAINS
(* ,@input)
答案 1 :(得分:1)
我以不同的方式构建数据。这50个列的类型都是一样的吗?既然你正在使用“喜欢”,我将假设它们都是varchar列。为什么不有3个表,'MyTable',一个包含字符串数据的表(无论它是什么),以及一个引用两者的连接表。
此时,您的查询变为:
select mt.*
from MyTable mt
inner join JoinTable jt
on jt.MyTableId = mt.Id
inner join DataTable dt
on dt.Id = jt.DataTableId
where dt.Data like @Input
显然,在SO上,我们看到很多答案很简单,“你的数据结构错误。重做它。”这并不总是最有帮助的。如果出于某种原因(围绕数据库结构的官僚主义,对此结构的遗留依赖性等),您无法重构它,您需要意识到您正在转动这些列。此时,您需要查看用于旋转此选项的选项,这将根据此数据库的分析/事务(读/写重)的方式而有所不同。如果您读得很重,您可以将数据复制到每次更新“MyTable”时更新的数据透视表中。如果您更具事务性,则函数或视图将至少抽象此透视结构,但查询将是昂贵的。 MS SQL全文搜索功能类似于复制数据和更新插入,并且根据“喜欢”查询的性质,可以更快地读取。
答案 2 :(得分:0)
如果您不需要实时数据,则可以选择数据仓库方案。
SELECT ID, Col1 FROM MyTable UNION ALL SELECT ID, Col2 FROM MyTable UNION ALL SELECT ID, Col3 FROM MyTable
这使您可以简化原始选择并保持同等性能
SELECT mt.*
FROM MyTable mt
INNER JOIN MyDWTable mdwt ON mdwt.ID = mt.ID
WHERE mdwt.Value LIKE @Input