在 SQL Server 中检查逗号分隔字符串中是不是存在子字符串的最有效方法

Posted

技术标签:

【中文标题】在 SQL Server 中检查逗号分隔字符串中是不是存在子字符串的最有效方法【英文标题】:Most effective way to check sub-string exists in comma-separated string in SQL Server在 SQL Server 中检查逗号分隔字符串中是否存在子字符串的最有效方法 【发布时间】:2016-01-21 02:18:16 【问题描述】:

我有一个可用的逗号分隔列表列,其值类似于

Product1, Product2, Product3

我需要搜索给定的产品名称是否存在于该列中。

我使用了这个 SQL,它运行良好。

Select * 
from ProductsList 
where productname like '%Product1%'

此查询运行缓慢。有没有更有效的方法可以在逗号分隔列表中搜索产品名称以提高查询性能?

请注意,在执行任何其他选择语句之前,我必须搜索逗号分隔的列表。

【问题讨论】:

规范化你的表。 如果不重新设计东西,这与你将获得的一样好,直到人们开始告诉你做一些疯狂的事情,比如全文索引值。顺便说一句,like '%Product1%' 也将匹配 Product10 和 Product101。 Comma Delimited SQL string Need to separated的可能重复 【参考方案1】:

用户定义的字符串逗号分隔函数

Create FUNCTION [dbo].[BreakStringIntoRows] (@CommadelimitedString   varchar(max))
RETURNS   @Result TABLE (Column1   VARCHAR(max))
AS
BEGIN
        DECLARE @IntLocation INT
        WHILE (CHARINDEX(',',    @CommadelimitedString, 0) > 0)
        BEGIN
              SET @IntLocation =   CHARINDEX(',',    @CommadelimitedString, 0)      
              INSERT INTO   @Result (Column1)
              --LTRIM and RTRIM to ensure blank spaces are   removed
              SELECT RTRIM(LTRIM(SUBSTRING(@CommadelimitedString,   0, @IntLocation)))   
              SET @CommadelimitedString = STUFF(@CommadelimitedString,   1, @IntLocation,   '') 
        END
        INSERT INTO   @Result (Column1)
        SELECT RTRIM(LTRIM(@CommadelimitedString))--LTRIM and RTRIM to ensure blank spaces are removed
        RETURN 
END


Declare @productname Nvarchar(max)
 set @productname='Product1,Product2,Product3'
select * from product where [productname] in(select * from [dbo].[![enter image description here][1]][1][BreakStringIntoRows](@productname)) 

【讨论】:

【参考方案2】:

Felix 是对的,“正确答案”是规范化您的表格。虽然,也许您有 500k 行代码希望此列按原样存在。因此,您的下一个最佳(非破坏性)答案是:

    创建一个表来保存规范化数据:

    CREATE TABLE ProductsList2 (ProductId INT, ProductName VARCHAR)
    

    创建一个触发器,在 UPDATE/INSERT/DELETE 上通过将字符串“Product1,Product2,Product3”拆分为三个记录来维护 ProductList2。

    索引您的新表。

    查询您的新表:

    SELECT * 
    FROM ProductsList 
    WHERE ProductId IN (SELECT x.ProductId 
                        FROM ProductsList2 x 
                        WHERE x.ProductName = 'Product1')
    

【讨论】:

以上是关于在 SQL Server 中检查逗号分隔字符串中是不是存在子字符串的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 的逗号分隔输入字符串

sql server里如何将一组用逗号分隔的字符串分解并插入到另一张表中,比如:11873,27827, 也可能是好多

如何检查 SQL Server 2008 表中字符串列中的 id

我想拆分用逗号分隔的字符串并在 SQL Server 中另存为新行 [重复]

SQL Server 2005 中的逗号分隔值插入

拆分逗号分隔参数传递给SQL Server 2008 R2中的存储过程