目前,我用这个:
CREATE FUNCTION [dbo].[SEARCH_SINGLE] (
@langId INT = 4,
@searchString VARCHAR(MAX) = NULL
)
RETURNS TABLE
AS
RETURN
WITH words AS (
SELECT * FROM [dbo].splitstring(@searchString, ' ')
)
SELECT DISTINCT
...
FROM
...
WHERE
...
AND (
EXISTS(SELECT t2.Name FROM words t2 WHERE a.[FIRSTNAME] like '%'+t2.Name+'%')
OR EXISTS(SELECT t2.Name FROM words t2 WHERE a.[LASTNAME] like '%'+t2.Name+'%')
OR EXISTS(SELECT t2.Name FROM words t2 WHERE c.[CITY] like '%'+t2.Name+'%')
OR EXISTS(SELECT t2.Name FROM words t2 WHERE j.[PROMO_YEAR] like '%'+t2.Name+'%')
OR EXISTS(SELECT t2.Name FROM words t2 WHERE e.[EMPLOYOR] like '%'+t2.Name+'%')
)
它有效,但它会返回与输入的单词 匹配的所有记录。 我需要返回与至少一列中的所有字词匹配的记录。
例如,如果我们只考虑firstname
和lastname
:
实际上,对于像“John Doe McDonald”这样的搜索,我需要像这样模拟一个WHERE
:
WHERE
(
a.[FIRSTNAME] like '%John%'
OR a.[LASTNAME] like '%John%'
OR c.[CITY] like '%John%'
OR j.[PROMO_YEAR] like '%John%'
OR e.[EMPLOYOR] like '%John%'
)
AND (
a.[FIRSTNAME] like '%Doe%'
OR a.[LASTNAME] like '%Doe%'
OR c.[CITY] like '%Doe%'
OR j.[PROMO_YEAR] like '%Doe%'
OR e.[EMPLOYOR] like '%Doe%'
)
AND (
a.[FIRSTNAME] like '%McDonald%'
OR a.[LASTNAME] like '%McDonald%'
OR c.[CITY] like '%McDonald%'
OR j.[PROMO_YEAR] like '%McDonald%'
OR e.[EMPLOYOR] like '%McDonald%'
)
理想情况下,如果在整个数据库的5列中找不到单词,只需忽略(“John Doe sjdhf67df”应返回“John Doe”......)。
我试图动态构建查询但是我在返回结果时遇到了一些问题,因为我们无法在函数中使用EXEC
...
我们不暂时考虑全文搜索!
如何我可以修改我的功能以获得预期的结果?
答案 0 :(得分:0)
我终于回到了以下解决方案:
CREATE FUNCTION [dbo].[SEARCH_SINGLE] (
@langId INT = 4,
@searchString VARCHAR(MAX) = NULL
)
RETURNS TABLE
AS
RETURN
WITH
words AS (
SELECT * FROM [dbo].splitstring(@searchString, ' ')
),
results AS (
SELECT DISTINCT
a.[ID] as Id,
a.[LASTNAME] as LastName,
a.[FIRSTNAME] as FirstName,
d.[COUNTRY_LABEL] as CountryLabel,
c.[CITY] as City,
j.[PROMO_YEAR] as PromoYear,
CASE WHEN EXISTS(SELECT t2.Name FROM words t2 WHERE a.[FIRSTNAME] like '%'+t2.Name+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT t2.Name FROM words t2 WHERE a.[LASTNAME] like '%'+t2.Name+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT t2.Name FROM words t2 WHERE c.[CITY] like '%'+t2.Name+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT t2.Name FROM words t2 WHERE j.[PROMO_YEAR] like '%'+t2.Name+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT t2.Name FROM words t2 WHERE e.[EMPLOYOR] like '%'+t2.Name+'%') THEN 1 ELSE 0 END as Nb
FROM
...
WHERE
...
)
SELECT
Id,
LastName,
FirstName,
CountryLabel,
City,
PromoYear,
FROM
results
WHERE
Nb = (SELECT MAX(Nb) FROM results)
AND Nb <> 0
它似乎涵盖了我的所有要求。