使用 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
列中具有 ello
或 yel
的所有行。所以在这个例子中,应该 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], '%')
)
)
我试图在我的 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
列中具有 ello
或 yel
的所有行。所以在这个例子中,应该 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], '%')
)
)