Sql server SQL查询-递归求精
我试图将一串由空格分隔的单词传递到存储过程中,我想做的是对这些单词执行SELECT,这样每个后续SELECT都会查询前面的结果集。我一直在研究如何使用递归CTE实现这一点,但我无法找到一种正确的方法来设置锚和终止符,以使递归正常工作。我知道我可以在服务器端代码(C#)上实现这一点,但我不想为了我知道可以在那里实现的事情而重复调用DB。下面是存储的过程,减去拆分字符串的任何拆分操作类型和我所做的任何黑客递归尝试(即,它所做的只是返回一个关键字的结果集):Sql server SQL查询-递归求精,sql-server,tsql,common-table-expression,Sql Server,Tsql,Common Table Expression,我试图将一串由空格分隔的单词传递到存储过程中,我想做的是对这些单词执行SELECT,这样每个后续SELECT都会查询前面的结果集。我一直在研究如何使用递归CTE实现这一点,但我无法找到一种正确的方法来设置锚和终止符,以使递归正常工作。我知道我可以在服务器端代码(C#)上实现这一点,但我不想为了我知道可以在那里实现的事情而重复调用DB。下面是存储的过程,减去拆分字符串的任何拆分操作类型和我所做的任何黑客递归尝试(即,它所做的只是返回一个关键字的结果集): 听起来像是使用全文索引的理想方案,这样您就
听起来像是使用全文索引的理想方案,这样您就可以使用CONTAINS() 如果您没有访问全文索引的权限,可以尝试将字符串拆分为一个表,然后加入该表,然后计数重复项(通过对主键进行分区)。未测试的示例:
CREATE FUNCTION [dbo].[fnc_Split]
(
@Data VARCHAR(2000) ,
@Sep VARCHAR(5)
)
RETURNS @Temp TABLE
(
Id INT IDENTITY(1, 1) ,
Data NVARCHAR(100)
)
AS
BEGIN
DECLARE @Cnt INT
SET @Cnt = 1
WHILE ( CHARINDEX(@Sep, @Data) > 0 )
BEGIN
INSERT INTO @Temp
( data
)
SELECT Data = LTRIM(RTRIM(SUBSTRING(@Data, 1, CHARINDEX(@Sep, @Data) - 1)))
SET @Data = SUBSTRING(@Data, CHARINDEX(@Sep, @Data) + 1, LEN(@Data))
SET @Cnt = @Cnt + 1
END
INSERT INTO @Temp
( data )
SELECT Data = LTRIM(RTRIM(@Data))
RETURN
END
GO
DECLARE @SearchString VARCHAR(MAX)
SET @SearchString = 'blood HIV white'
--#### Build Pattern Table
DECLARE @PatternTable TABLE
(
ID INT NOT NULL ,
PATTERN VARCHAR(50)
)
INSERT INTO @PatternTable
( ID ,
PATTERN
)
SELECT ID ,
CASE WHEN ID = 1 THEN Data + '%'
ELSE '% ' + Data + '%'
END AS Data
FROM fnc_Split(@SearchString, ' ');
--#### Fetch list of matching Primary keys (repeat CTEs for each column)
WITH PrepSearch ( PrimaryKey, MatchedWords )
AS ( SELECT PrimaryKey ,
COUNT(PrimaryKey) OVER ( PARTITION BY PrimaryKey ) AS MatchedWords
FROM dbo.RolodexTestDB P ( NOLOCK )
INNER JOIN @PatternTable S ON P.Methodology LIKE S.PATTERN COLLATE DATABASE_DEFAULT
),
SearchResults ( PRO_CODE )
AS ( SELECT PrimaryKey
FROM PrepSearch
WHERE MatchedWords = (SELECT COUNT(ID) FROM @PatternTable)
GROUP BY PrimaryKey
)
SELECT *
FROM SearchResults
“每个后续SELECT查询之前的结果集”是什么意思。在非TSQL术语中,您试图实现什么?您能提供@searchQuery的样本值、RolodexTestDB中的一些样本数据和所需结果吗?否则很难准确解释您试图执行的操作。抱歉-我的解释不正确。@searchQuery的样本值可能是:“血色HIV-white”-我需要的是执行上述查询3次(或其他解决方案,完成相同的事情)-每次运行查询时,结果集都会被过滤(因此,第一次运行时,我会得到任何包含第一个项的记录;然后,我会使用第二个项对该结果集再次运行查询,依此类推).希望有意义。不,至少对我来说没有意义。过滤意味着所有术语都必须存在?
CREATE FUNCTION [dbo].[fnc_Split]
(
@Data VARCHAR(2000) ,
@Sep VARCHAR(5)
)
RETURNS @Temp TABLE
(
Id INT IDENTITY(1, 1) ,
Data NVARCHAR(100)
)
AS
BEGIN
DECLARE @Cnt INT
SET @Cnt = 1
WHILE ( CHARINDEX(@Sep, @Data) > 0 )
BEGIN
INSERT INTO @Temp
( data
)
SELECT Data = LTRIM(RTRIM(SUBSTRING(@Data, 1, CHARINDEX(@Sep, @Data) - 1)))
SET @Data = SUBSTRING(@Data, CHARINDEX(@Sep, @Data) + 1, LEN(@Data))
SET @Cnt = @Cnt + 1
END
INSERT INTO @Temp
( data )
SELECT Data = LTRIM(RTRIM(@Data))
RETURN
END
GO
DECLARE @SearchString VARCHAR(MAX)
SET @SearchString = 'blood HIV white'
--#### Build Pattern Table
DECLARE @PatternTable TABLE
(
ID INT NOT NULL ,
PATTERN VARCHAR(50)
)
INSERT INTO @PatternTable
( ID ,
PATTERN
)
SELECT ID ,
CASE WHEN ID = 1 THEN Data + '%'
ELSE '% ' + Data + '%'
END AS Data
FROM fnc_Split(@SearchString, ' ');
--#### Fetch list of matching Primary keys (repeat CTEs for each column)
WITH PrepSearch ( PrimaryKey, MatchedWords )
AS ( SELECT PrimaryKey ,
COUNT(PrimaryKey) OVER ( PARTITION BY PrimaryKey ) AS MatchedWords
FROM dbo.RolodexTestDB P ( NOLOCK )
INNER JOIN @PatternTable S ON P.Methodology LIKE S.PATTERN COLLATE DATABASE_DEFAULT
),
SearchResults ( PRO_CODE )
AS ( SELECT PrimaryKey
FROM PrepSearch
WHERE MatchedWords = (SELECT COUNT(ID) FROM @PatternTable)
GROUP BY PrimaryKey
)
SELECT *
FROM SearchResults