使用单值参数搜索 SQL 中的多值逗号分隔字符串

Using a single value parameter to search a multi value comma separated string in SQL

在我的 SQL 查询中,我有一个单值参数 @MandatoryGroup,它为这样的列表的其中一个 ID 号返回一个整数值

202  Group A
203  Group B
204  Group C
205  Group D

所以@MandatoryGroup 的值可以是 202

在我 table 的人中,人们通过包含逗号分隔列表的列链接到组,例如如果一个人属于 A、C 和 D 组,则列中的值 TblPeople.PeopleCourseGroup = 202,204,205

我正在尝试找出如何找到包含组 202 的所有记录。下面显示了我能得到的最接近的记录,但没有错误,但这只给我结果,其中人们只在组 202 中。记录与找不到值 202,204,205。

SELECT     
TblPeople.PeopleId
,TblPeople.PeopleSurname
,TblPeople.PeopleForename
,TblPeople.PeopleCourseGroup

FROM 
TblPeople

WHERE 
CONVERT(Varchar(10),@MandatoryGroup) = TblPeople.PeopleCourseGroup

我试过 IN 和 LIKE 的各种组合,但都没有成功。网络搜索带回了很多关于多值参数的结果,但我看不到任何与此相反的做法。

艾尔斯

编辑:

我必须指出,这个问题描述的问题与您在以下问题中提出的问题类似: 该问题的答案(由@Juan Carlos Oropeza 提供)也适用于该问题,特别是使用 WHERE .. LIKE 结构:

WHERE  ',' + PeopleCourseGroup + ',' LIKE '%,' + '202' + ',%'

我的初步回答如下:

您需要创建一个字符串拆分函数:

CREATE FUNCTION tfnSplit
(
    @Source VARCHAR( MAX ),
    @Delimitor VARCHAR( 100 )
)
RETURNS @Results TABLE( ID INT PRIMARY KEY, Value VARCHAR( MAX ))
AS
BEGIN
    DECLARE @CurrentPosition BIGINT, @NextPosition BIGINT, @DelimitorLength INT
    DECLARE @ID INT -- Performance improvement of 15% when ID is incremented manually

    SET @ID = 1
    SET @Source = @Source + @Delimitor
    SET @DelimitorLength = DATALENGTH( @Delimitor )

    SET @CurrentPosition = 1 
    SET @NextPosition = CHARINDEX( @Delimitor, @Source, @CurrentPosition )

    WHILE @NextPosition > 0
    BEGIN
        INSERT @Results( ID, Value )
        SELECT @ID, SUBSTRING( @Source, @CurrentPosition, @NextPosition - @CurrentPosition )

        SET @ID = @ID + 1
        SET @CurrentPosition = @NextPosition + @DelimitorLength
        SET @NextPosition = CHARINDEX( @Delimitor, @Source, @CurrentPosition )
    END

    RETURN
END;

然后 CROSS APPLY 在您的代码中:

 SELECT     
    TblPeople.PeopleId
    ,TblPeople.PeopleSurname
    ,TblPeople.PeopleForename
    ,TblPeople.PeopleCourseGroup
    FROM TblPeople
        CROSS APPLY dbo.tfnSplit( PeopleCourseGroup, ',' ) AS Groups
    WHERE Groups.Value = '202'

将关系存储为逗号分隔列表是糟糕的设计,因为您在加入 table 时会遇到问题(正如您遇到的那样)。在您的情况下,您应该创建另一个 table,比如 PeopleGroups 来存储该关系:

CREATE TABLE PeopleGroups( PeopleId INT, GroupID INT )

您可以选择添加外键约束。