在列中搜索文本
Posted
技术标签:
【中文标题】在列中搜索文本【英文标题】:Search a text in a column 【发布时间】:2019-10-23 08:07:29 【问题描述】:我有一个 ASP.NET 页面,并且有一个表格看起来像
Create table Test(id int, Users Varchar(MAX));
Insert into Test select 1, 'admin;operator;user1';
Insert into Test select 2, 'superadmin';
Insert into Test select 3, 'superadmin;admin';
任何测试行都可以包含多个用户,因此我将它们用分号分隔。我想在客户端在文本框中搜索时返回值,他们只会插入:admin 我只想返回包含 admin 的行。
我不能用
select id,Users where Users like '%admin%'
因为在这种情况下,查询将返回包含超级管理员的第二列和第三列。
我怎样才能得到真实的结果?
【问题讨论】:
问题是您存储的是分隔数据。修正你的设计,你就没有这个问题了。 在您的操作中需要分隔;
?
正如@Larnu 提到的,如果可能的话,改变设计,否则我看到的唯一选择是创建一个函数或存储过程,它将搜索字符串作为输入,首先拆分结果并将其存储在临时表(表变量)和文件过滤器并从那里返回结果
修复您的架构。那里没有第二和第三列,只有一列。即使拆分值,您也无法轻松查询这样存储的文本。您也无法加速此类查询,因为您无法索引各个值
感谢您的善意建议。但现在,我不能改变桌子的设计。因为这是一个令牌表并且有更多的列。一个令牌可以分配多个用户,所以在这种情况下,我必须分别为每个用户创建相同的令牌。
【参考方案1】:
您不应该存储分隔数据,如果可能,请规范您的数据库。 由于这并不总是可行的,因此您可以得到您想要的:
where CONCAT(';', Users, ';') like '%;admin;%'
【讨论】:
这仍然需要全表扫描才能找到匹配项。 这将返回我所需要的。谢谢 HoneyBadger。 似乎 OP 认为分隔数据可以加快他们的数据库速度,@PanagiotisKanavos(请参阅他们在我的回答下的评论)。 @Maestro00 不是。在您修复架构之前,这是解决方法。【参考方案2】:正如我在评论中提到的,您需要修复您的设计;你现在正在做的是打破基本的范式规则之一。这意味着,每个用户只有一行:
CREATE TABLE Test (uid int IDENTITY,
id int,
Username nvarchar(128));
INSERT INTO Test (id,
Username)
VALUES (1, N'admin'),
(1, N'operator'),
(1, N'user1'),
(2, N'supermadmin'),
(3, N'superadmin'),
(3, N'admin');
然后您可以简单地使用=
运算符:
SELECT *
FROM Test
WHERE Username = N'admin';
【讨论】:
谢谢拉努。我会考虑你的建议。但是我的一些列包含很长的加密数据,如果我只为一个项目创建多行,那会使我的数据库变慢。 使用LIKE
搜索用户会使其变慢,@Maestro00。存储格式良好的非分隔数据将使其更快,而不是更慢,因为您能够正确索引它。如果您认为分隔数据会加快处理速度,那您就大错特错了。
@Maestro00 不,不会的。您所做的已经使您的数据库速度变慢了几个数量级。您现在必须扫描整个表并在值内搜索,而不是使用索引来查找匹配项。对于 10K 行,这至少比使用索引慢 10K 倍 - SQL 中的文本搜索慢,肯定比相等比较慢【参考方案3】:
我猜你可以试试下面的查询
SELECT * FROM #tmpTest where users like '%Admin%' AND Users not like 'superAdmin'
【讨论】:
'superadmin'
和 'User1'
是成员的行呢?
你是对的,我的错我没有意识到这种情况谢谢。
感谢您的回答。但此案不仅与管理员有关。可能还有其他用户名,例如 admin1;meadmin以上是关于在列中搜索文本的主要内容,如果未能解决你的问题,请参考以下文章