我想找到一个JSON数组包含一个或多个特定值的多行。有时所有匹配项都需要匹配(AND
s,有时只匹配某些(OR
s,有时需要两者结合(AND
和OR
)。
这是在Microsoft SQL Server 2017中。
我尝试在select中执行AS
语句,但导致为子查询创建的别名稍后在子查询中无法识别。
下面的例子有效,它看起来没有什么作用,并且具有代码重复。
我怎么只指定一次SELECT VALUE FROM OPENJSON(JsonData, '$.categories'
?也许还有其他方法可以做到这一点?
DECLARE @TestTable TABLE
(
Id int,
JsonData nvarchar(4000)
);
INSERT INTO @TestTable
VALUES
(1,'{"categories":["one","two"]}'),
(2,'{"categories":["one"]}'),
(3,'{"categories":["two"]}'),
(4,'{"categories":["one","two","three"]}');
SELECT [Id]
FROM @TestTable
WHERE ISJSON(JsonData) = 1
-- These two lines are the offending parts of code
AND 'one' in (SELECT VALUE FROM OPENJSON(JsonData, '$.categories'))
AND 'two' in (SELECT VALUE FROM OPENJSON(JsonData, '$.categories'));
表格式不能更改,尽管我可以添加计算列-如果需要的话。
答案 0 :(得分:0)
好吧,我不确定这是否对您有帮助...
将嵌套数组转换为派生表以将其用作CTE可能会有所帮助。检查一下:
DECLARE @TestTable TABLE
(
Id int,
JsonData nvarchar(4000)
);
INSERT INTO @TestTable
VALUES
(1,'{"categories":["one","two"]}'),
(2,'{"categories":["one"]}'),
(3,'{"categories":["two"]}'),
(4,'{"categories":["one","two","three"]}');
-这是查询
WITH JsonAsTable AS
(
SELECT Id
,JsonData
,cat.*
FROM @TestTable tt
CROSS APPLY OPENJSON(tt.JsonData,'$.categories') cat
)
SELECT *
FROM JsonAsTable
该方法非常接近您自己形成的查询。结果是一个表,每个数组项只有一行。形式Id
是重复的分组键,key
是数组中的序数位置,而value
是您要搜索的单词之一。
在查询中,您可以像在该位置使用任何其他表一样使用JsonAsTable
。
但是-您将需要重复的FROM OPENJSON
谓词...,而不是重复的EXISTS()
查询...
一个骇人听闻的解决方案可能是这样的:
SELECT Id
,JsonData
,REPLACE(REPLACE(REPLACE(JsonData,'{"categories":[','",'),']}',',"'),'","',',')
FROM @TestTable
这将以字符串形式返回所有嵌套数组值,并以逗号分隔。您可以使用LIKE
模式进行查询...不过您也可以将其作为计算列返回...