我已经得到了这个查询,它可以正确地循环一组单词并在每个单词的某些字段上执行类似的条件,并在需要时搜索DOB。
任何人都可以在需要While循环的过程中看到这样做的方法吗?我无法找到使用STRING_SPLIT执行此操作的方法,但我无法使用此方法添加LIKE。
SET STATISTICS IO ON
SET STATISTICS TIME ON
--what will become stored proc parameters
DECLARE @searchwords NVARCHAR(max) = 'mary jo' --can accept many search words
DECLARE @LowerDate date = '01 Jan 1980' --could be NULL
DECLARE @UpperDate date = '31 Dec 1980' --could be NULL
--local variables
DECLARE @word NVARCHAR(50)
Declare @ID int
Create Table #SearchWords
(
ID int IDENTITY(1,1),
Word varchar(50)
)
Create Table #Results
(
ClientID int,
FirstName varchar(50),
LastName varchar(50),
VerificationCode varchar(100),
DOB date
)
Insert into #SearchWords
(
Word
)
SELECT
value
FROM
STRING_SPLIT(@searchwords, ' ')
WHERE
RTRIM(value) <> ''
While (Select Count(*) From #SearchWords) > 0
Begin
Select Top 1
@ID = ID,
@Word = Word
From
#SearchWords
INSERT INTO #Results
(
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
)
SELECT
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM
Client
WHERE
(FirstName like '%' + @Word + '%' or
LastName like '%' + @Word + '%' or
VerificationCode like '%' + @Word + '%')
Delete #SearchWords Where ID = @ID
End
IF (@LowerDate IS NOT NULL and @UpperDate IS NOT NULL)
BEGIN
INSERT INTO #Results
(
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
)
SELECT
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM
Client
WHERE
(DOB >= @LowerDate and DOB <= @UpperDate)
END
select * from #Results
drop table #Results
drop table #SearchWords
答案 0 :(得分:1)
尝试使用以下查询
SELECT
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM Client c
WHERE EXISTS(
SELECT *
FROM #SearchWords s
WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%'))
OR (c.LastName LIKE CONCAT('%',s.Word,'%'))
OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%'))
)
AND DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB)
评论中问题的变体
SELECT
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
INTO #Result
FROM Client c
WHERE EXISTS(
SELECT *
FROM #SearchWords s
WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%'))
OR (c.LastName LIKE CONCAT('%',s.Word,'%'))
OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%'))
)
AND DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB)
IF(EXISTS(SELECT * FROM #Result))
BEGIN
SELECT *
FROM #Result
END
ELSE
BEGIN
SELECT
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM Client
WHERE DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB)
END
DROP TABLE #Result
没有临时表的变体
SELECT TOP 1 WITH TIES
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM
(
SELECT
1 RowPriority,
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM Client c
WHERE EXISTS(
SELECT *
FROM #SearchWords s
WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%'))
OR (c.LastName LIKE CONCAT('%',s.Word,'%'))
OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%'))
)
AND DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB)
UNION ALL
SELECT
2 RowPriority,
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM Client c
WHERE DOB BETWEEN ISNULL(@LowerDate,DOB) AND ISNULL(@UpperDate,DOB)
) q
ORDER BY RowPriority
另一个变种
SELECT TOP 1 WITH TIES
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM
(
-- the first scenario - we use only words filter without the DOB filter
SELECT
1 RowPriority, -- max priority
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM Client c
WHERE EXISTS(
SELECT *
FROM #SearchWords s
WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%'))
OR (c.LastName LIKE CONCAT('%',s.Word,'%'))
OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%'))
)
AND @LowerDate IS NULL
UNION ALL
-- the second scenario - we use words and DOB filters
SELECT
2 RowPriority,
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM Client c
WHERE EXISTS(
SELECT *
FROM #SearchWords s
WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%'))
OR (c.LastName LIKE CONCAT('%',s.Word,'%'))
OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%'))
)
AND DOB BETWEEN @LowerDate AND @UpperDate
-- the third scenario - we use only DOB filter
SELECT
3 RowPriority, -- min priority
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM Client c
WHERE (SELECT COUNT(*) FROM #SearchWords)=0
AND DOB BETWEEN @LowerDate AND @UpperDate
) q
ORDER BY RowPriority
具有辅助变量的变体
-- an auxiliary variable
DECLARE @Scenario int=CASE
WHEN (SELECT COUNT(*) FROM #SearchWords)>0 THEN IIF(@LowerDate IS NULL,1,2)
WHEN (SELECT COUNT(*) FROM #SearchWords)=0 AND @LowerDate IS NOT NULL THEN 3
END
SELECT
ClientID,
FirstName,
LastName,
VerificationCode,
DOB
FROM Client c
WHERE
(
(
@Scenario IN(1,2)
AND EXISTS(
SELECT *
FROM #SearchWords s
WHERE (c.FirstName LIKE CONCAT('%',s.Word,'%'))
OR (c.LastName LIKE CONCAT('%',s.Word,'%'))
OR (c.VerificationCode LIKE CONCAT('%',s.Word,'%'))
)
)
OR
@Scenario=3 -- this scenario doesn't use word filter
)
AND
(
(@Scenario IN(2,3) AND DOB BETWEEN @LowerDate AND @UpperDate)
OR
@Scenario=1 -- this scenario doesn't use DOB filter
)