请参阅我创建的数据库表,以解释我的问题:
CREATE Table Test(id int not null IDENTITY,data varchar(100))
INSERT INTO Test(data) values ('Simon')
INSERT INTO Test(data) values ('David;James;Michael')
请参阅下面的SQL语句:
select *
from Test
where data like '%_James%'
or data like '%James;%'
我相信,无论表格单元格中是否有一个名称或多个名称,我都会发现詹姆斯,假设半冒号总是用作分隔符。
另一位开发人员说他会将值加载到一个数组中(在ASP.NET或任何编程语言中)并循环遍历数组以找到完全匹配,但是我不相信这一步是必要的,因为'James'永远都会找到。这一步是必要的吗?
答案 0 :(得分:2)
最好在查询中进行过滤。如果有数百万条记录怎么办?您不希望首先检索所有这些,只是为了过滤。
假设您必须坚持使用这种非规范化架构,我会这样做。前两种情况可以使用data
列上的索引。假设数据从不具有前导或尾随分号:
select *
from Test
where data = 'James'
or data like 'James;%'
or data like '%;James;%'
or data like '%;James'
答案 1 :(得分:1)
使用你粘贴的SQL,如果有至少一个字符它(例如,“2James”,“BJames”,“2Jamesey”将匹配)之前,或詹姆斯会被发现,如果有一个分号“詹姆斯”后(例如,“2James;”,“BJames;”,“James”)。但是“詹姆斯”本身并不匹配,因为你使用了下划线。
目前尚不清楚您正在尝试做什么。你只想找到与“詹姆斯”这个词完全匹配的行(在“詹姆斯”之前和之后有“单词”边界,或者你想要“詹姆斯”出现在列中任何地方的行,即使它是大词的一部分,例如“詹姆斯敦”)。您可以通过添加or data = 'James'
进行修复。我不确定下划线的事情是否正在做你想要的事情,因为我不确定你的总体目标是什么。您可能需要或可能不需要对查询进行进一步更改。
根据您对表中数据的清晰程度的信心,您可以编写一个语句来执行您所说的内容。我会将搜索保留在SQL语句中,而不是将记录拉出并循环遍历数组中的值,因为在某些情况下这可能会变得低效。
答案 2 :(得分:1)
不,不需要在数组中加载值 - 在任何情况下都会对性能造成很大影响。
说过SQL有点奇怪 - 如果你想插入由;
分隔的名字,我认为你需要:
INSERT INTO Test(data) values ('David;James;Michael')
如果你确保每个名字都以分隔符开头和结尾会更好:
INSERT INTO Test(data) values (';David;James;Michael;')
然后你可以使用
SELECT * FROM Test WHERE data like '%;James;%'
并确保始终获得正确的结果。
最后但并非最不重要的是,可以在单个列中填充多个值,但这不是在SQL数据库中做的最好的事情,最好将名称保存在不同的表中的不同行中然后有一个交叉引用(规范化结构)。