使用单值参数搜索 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 )
您可以选择添加外键约束。
在我的 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 的各种组合,但都没有成功。网络搜索带回了很多关于多值参数的结果,但我看不到任何与此相反的做法。
艾尔斯
编辑:
我必须指出,这个问题描述的问题与您在以下问题中提出的问题类似:
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 )
您可以选择添加外键约束。