我正在尝试在WHERE
过滤器的JSON
子句中使用部分搜索。我正在传递一个,
分隔字符串,并希望在where语句中将其分开。
例如:
示例表:
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"
}'
我正在尝试从具有'%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
将返回多于1行。我可以切换为使用IN
子句,但无法执行部分搜索。有关如何解决此问题的任何建议?
编辑:
基于上述过滤器,输出应返回在ello
列中具有yel
或SomeObject
的所有行。因此,在此示例中,应返回第1行和第2行。
答案 0 :(得分:1)
一种方法是使用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以确保每个{{1 }}返回。
答案 1 :(得分:1)
也许这会像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')
,',',']%[' ) + ']%'
)
答案 2 :(得分:1)
如果我对您的理解正确,则可以尝试以下操作:
-- 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], '%')
)
)