使用单个值参数在SQL

时间:2016-06-03 14:32:46

标签: sql-server-2008-r2 ssrs-2008-r2

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

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

所以@MandatoryGroup的值可能是202

在我的人员表中,人们通过包含逗号分隔列表的列链接到组,例如如果一个人在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的各种组合而没有成功。网络搜索带来了大量关于多值参数的结果,但我无法看到与此相反的任何相关内容。

EILS

1 个答案:

答案 0 :(得分:1)

编辑:

我必须指出,此问题描述的问题类似于您提出的问题:Using CASE in WHERE Statement when parameter has multiple values 答案(由@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'

将关系存储为昏迷列表是不好的设计,因为您在连接表时遇到问题(正如您所遇到的那样)。在您的情况下,您应该创建另一个表,比如PeopleGroups来存储这些关系:

CREATE TABLE PeopleGroups( PeopleId INT, GroupID INT )

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