对 JSON 数据的 SQL LIKE 查询
Posted
技术标签:
【中文标题】对 JSON 数据的 SQL LIKE 查询【英文标题】:SQL LIKE query on JSON data 【发布时间】:2019-11-29 19:41:23 【问题描述】:我将 JSON 数据(无架构)存储在 SQL Server 列中,需要对其运行搜索查询。
例如(不是实际数据)
[
"Color":"Red",
"Make":"Mercedes-Benz"
,
"Color":"Green",
"Make":"Ford"
,
]
SQL Server 2017 具有 JSON_XXXX 方法,但它们适用于已知架构。在我的例子中,对象的模式没有精确定义并且可能会改变。
目前要搜索列,例如找到 Make=Mercedes-Benz。我正在使用搜索短语“%\"Make\":\"Mercedes-Benz\"%"。如果使用确切的品牌名称,这非常有效。我希望用户也能够使用部分名称进行搜索,例如只需输入“Benz”或“merc”。
是否可以使用适合我的通配符构建 SQL 查询?还有其他选择吗?
【问题讨论】:
您可以在不定义数据的情况下使用OPENJSON
,但是从中获取有用的数据是很困难的。样本数据和预期结果会很好
这是非结构化数据的问题。那是你唯一的问题。如果你解决了这个问题,所有其他问题都会消失。接受 JSON 的 RDMS 无法解决这个问题,MongoDB 之类的东西也无法解决。
【参考方案1】:
一种可能的方法是将OPENJSON
与默认架构一起使用两次。使用默认架构,OPENJSON
returns 包含列 key
、value
和 type
的表,您可以将它们用于您的 WHERE
子句。
表:
CREATE TABLE #Data (
Json nvarchar(max)
)
INSERT INTO #Data
(Json)
VALUES
(N'[
"Color":"Red",
"Make":"Mercedes-Benz"
,
"Color":"Green",
"Make":"Ford",
"Year": 2000
]')
声明:
SELECT
j1.[value]
-- or other columns
FROM #Data d
CROSS APPLY OPENJSON(d.Json) j1
CROSS APPLY OPENJSON(j1.[value]) j2
WHERE
j2.[key] LIKE '%Make%' AND
j2.[value] LIKE '%Benz%'
输出:
--------------------------
value
--------------------------
"Color":"Red",
"Make":"Mercedes-Benz"
【讨论】:
【参考方案2】:你可以用 ',' 分割 json 并像这样搜索:
WHERE EXISTS (SELECT *
FROM STRING_SPLIT(json_data, ',')
WHERE value LIKE '%\"Make\":%'
AND value LIKE '%Benz%'
);
【讨论】:
【参考方案3】:如果您碰巧运行的是不支持内置 JSON 函数(如 OPENJSON())的旧版本 SQL Server,则可以使用类似于以下的 SQL。
您可以在http://sqlfiddle.com/#!18/dd7a5 尝试测试此 SQL
注意:此 SQL 假定您正在搜索的键仅在每个记录/JSON 对象文字中出现一次(换句话说,您仅在每个记录/数据库行中存储具有唯一键的 JSON 对象文字)。另请注意,SELECT 查询是丑陋的,但它有效。
/* see http://sqlfiddle.com/#!18/dd7a5 to test this online*/
/* setup a test data table schema */
CREATE TABLE myData (
[id] [int] IDENTITY(1,1) NOT NULL,
[jsonData] nvarchar(4000)
CONSTRAINT [PK_id] PRIMARY KEY CLUSTERED
(
[id] ASC
)
);
/* Insert some test data */
INSERT INTO myData
(jsonData)
VALUES
('
"Color":"Red",
"Make":"Mercedes-Benz"
');
INSERT INTO myData
(jsonData)
VALUES
(
'
"Color":"White",
"Make":"Toyota",
"Model":"Prius",
"VIN":"123454321"
');
INSERT INTO myData
(jsonData)
VALUES
(
'
"Color":"White",
"Make":"Mercedes-Benz",
"Year": 2009
');
INSERT INTO myData
(jsonData)
VALUES
(
'
"Type":"Toy",
"Color":"White",
"Make":"Toyota",
"Model":"Prius",
"VIN":"99993333"
');
/* This select statement searches the 'Make' keys, within the jsonData records, with values LIKE '%oyo%'. This statement will return records such as 'Toyota' as the Make value. */
SELECT id, SUBSTRING(
jsonData
,CHARINDEX('"Make":', jsonData) + LEN('"Make":')
,CHARINDEX(',', jsonData, CHARINDEX('"Make":', jsonData) + LEN('"Make":')) - CHARINDEX('"Make":', jsonData) - LEN('"Make":')
) as CarMake FROM myData
WHERE
SUBSTRING(
jsonData
,CHARINDEX('"Make":"', jsonData) + LEN('"Make":"')
,CHARINDEX('"', jsonData, CHARINDEX('"Make":"', jsonData) + LEN('"Make":"')) - CHARINDEX('"Make":"', jsonData) - LEN('"Make":"')
) LIKE '%oyo%'
【讨论】:
以上是关于对 JSON 数据的 SQL LIKE 查询的主要内容,如果未能解决你的问题,请参考以下文章