使用 LIKE 和 JSON 对象进行部分搜索

Partial search with LIKE and JSON object

我试图在我的 WHERE 子句中使用 JSON 过滤器的部分搜索。我正在传递一个 , 分隔字符串,并希望将 where 语句中使用的字符串分开。

例如:

样本table:

create table NewTable
(
   Id int identity(1,1) primary key,
   SomeObject varchar(20),
   SomeText varchar(20)
)

INSERT INTO NewTable(SomeObject, SomeText)values ('hello', 'test1')
INSERT INTO NewTable(SomeObject, SomeText)values ('yellow', 'test2')
INSERT INTO NewTable(SomeObject, SomeText)values ('test1', 'test1')

这是通过的过滤器:

DECLARE @Filter NVARCHAR(MAX)

SET @Filter=N'{
  "SomeObject": "ello,yel"
}'

我正在尝试 select table 中具有 '%ello%''%yel%'

的所有内容
select * from newtable pm
where 
(pm.SomeObject IS NULL AND JSON_VALUE(@Filter,N'$.SomeObject') IS NULL OR pm.SomeObject LIKE '%' + (select value from string_split(ISNULL(JSON_VALUE(@Filter,N'$.SomeObject'),pm.SomeObject), ',')) + '%')

此查询部分有效。我有很多实例 subquery 将 return 多于 1 行。我可以切换到使用 IN 子句,但我无法执行部分搜索。关于如何解决这个问题有什么建议吗?

编辑:

基于上述过滤器,输出应 return SomeObject 列中具有 elloyel 的所有行。所以在这个例子中,应该 return 第 1 行和第 2 行。

一种方法是使用 OPENJSON 解析 JSON,然后 STRING_SPLIT 拆分分隔列表:

DECLARE @Filter nvarchar(MAX);

SET @Filter=N'{
  "SomeObject": "ello,yel"
}';
WITH CTE AS(
    SELECT NT.Id,
           NT.SomeObject,
           NT.SomeText,
           ROW_NUMBER() OVER (PARTITION BY NT.ID ORDER BY SS.[Value]) AS RN
    FROM dbo.NewTable NT
        CROSS APPLY OPENJSON(@Filter) OJ
        CROSS APPLY STRING_SPLIT(OJ.[value], ',') SS
    WHERE NT.SomeObject LIKE '%' + SS.[value] + '%')
SELECT Id,
       SomeObject,
       SomeText
FROM CTE
WHERE RN = 1;

然而,行可以匹配多次('Yellow' 包含字符串 'yel''ello'),您还需要一个 CTE 来确保每个 Id 返回。

也许这会匹配像 hello 这样的每个字符串,在像 %[hello]%[yellow]%

这样的串联正则表达式中是分开的
  select * from newtable pm
    where 
   (pm.SomeObject IS NULL AND 
  JSON_VALUE(@Filter,N'$.SomeObject') IS NULL 
    OR pm.SomeObject  LIKE '%[' + select 
  REPLACE
    (JSON_VALUE(@Filter,N'$.SomeObject')
            ,',',']%['  ) + ']%' 
     )

如果我理解正确的话,你可以试试这个:

-- Table
CREATE TABLE NewTable
(
   Id int identity(1,1) primary key,
   SomeObject varchar(20),
   SomeText varchar(20)
)
INSERT INTO NewTable(SomeObject, SomeText) VALUES ('hello', 'test1')
INSERT INTO NewTable(SomeObject, SomeText) VALUES ('yellow', 'test2')
INSERT INTO NewTable(SomeObject, SomeText) VALUES ('test1', 'test1')

-- JSON
DECLARE @Filter nvarchar(MAX)
SET @Filter = N'{
  "SomeObject": "ello,yel"
}'

-- Statement
SELECT pm.*
FROM NewTable pm
WHERE 
   -- 1. @Filter is null
   (ISJSON(@Filter) IS NULL) OR
   -- 2. $.SomeObject is empty text, @Filter = N'{"SomeObject": ""}'
   (JSON_VALUE(@Filter, '$.SomeObject') = N'') OR
   (JSON_VALUE(@Filter, '$.SomeObject') IS NULL) OR
   -- 3. Filter exists
   (
      (ISJSON(@Filter) IS NOT NULL) AND
      (JSON_VALUE(@Filter, '$.SomeObject') <> N'') AND
      (JSON_VALUE(@Filter, '$.SomeObject') IS NOT NULL) AND
      EXISTS (
         SELECT * 
         FROM STRING_SPLIT(JSON_VALUE(@Filter, '$.SomeObject'), ',') 
         WHERE pm.SomeObject LIKE CONCAT('%', [Value], '%')
      )
   )