如何使用 like 语句检查 where 子句中 json 数组的每一项
How to I check each item of a json array within the where clause using a like statement
我正在为我的应用程序中的搜索字段创建一个查询。该查询使用 "like" 关键字来检查记录中的各种字段。其中一个字段是未命名的 ([{}, {}]) json 数组。数组中的字段全部匹配。我希望能够在不使用索引的情况下检查数组的每个 "Value" 属性,即“$[0].value”。原因是数组的大小可能会有所不同。以下是数据示例:
[{
"MappedFieldName": "Customer",
"DataType": "string",
"Value": "Mapco Express"
}, {
"MappedFieldName": "Invoice Nbr",
"DataType": "string",
"Value": "31856174"
}, {
"MappedFieldName": "Invoice Document Date",
"DataType": "DateTime",
"Value": "2018-12-25 00:00:00.000"
}, {
"MappedFieldName": "Processing Date",
"DataType": "DateTime",
"Value": "2019-01-04 00:00:00.000"
}, {
"MappedFieldName": "Vendor Name",
"DataType": "string",
"Value": "Bullseye"
}, {
"MappedFieldName": "Account Nbr",
"DataType": "string",
"Value": "0048219"
}, {
"MappedFieldName": "Location #",
"DataType": "string",
"Value": "7520"
}, {
"MappedFieldName": "Amount Invoiced",
"DataType": "decimal",
"Value": "3580.43"
}, {
"MappedFieldName": "Amount Processed",
"DataType": "decimal",
"Value": "3580.43"
}, {
"MappedFieldName": "Invoice Start Date",
"DataType": "DateTime",
"Value": "2018-04-01 00:00:00.000"
}, {
"MappedFieldName": "Invoice End Date",
"DataType": "DateTime",
"Value": "2018-04-01 00:00:00.000"
}]
和
SELECT *
FROM [dbo].[Invoice]
WHERE JSON_VALUE(InvoiceData, '$.Value') like '%' + @searchText + '%'
此查询无效,因为我没有指定索引,即“$[0].Value”。
我明白了。我首先在搜索文本过滤器的记录的 json 字段上使用 OPENJSON,以获取找到文本的 json 数组部分的索引。接下来我使用索引where 子句标识要查找的数组索引。处理这个的代码如下。这将 return 在记录 json 数组中找到搜索文本的所有记录。
declare @searchText varchar(200) = '004'
declare @searchIndex varchar(10)
SELECT @searchIndex = [key]
FROM OPENJSON((SELECT InvoiceData FROM [dbo].[Invoice])) where Json_Value(value, '$.Value') like '%' + @searchText + '%'
SELECT *
FROM [dbo].[Invoice]
WHERE JSON_VALUE(InvoiceData, '$[' + @searchIndex +'].Value') like '%' + @searchText + '%'
这个答案可能会被简化。如果你有一个简单的答案,请随意post。
输入JSON
是一个JSON
对象的数组,具有固定结构(MappedFieldName
、DataType
和Value
键),所以另一种可能的方法是将 OPENJSON()
与显式架构一起使用到 return 一个 table 以及您在 WITH
子句中定义的列。使用这种方法,您可以过滤 invoices
table and/or 从输入 JSON
:
中获取更多信息
Table:
CREATE TABLE Invoices (
InvoiceData nvarchar(max)
)
INSERT INTO Invoices
(InvoiceData)
VALUES
(N'[{ "MappedFieldName": "Customer", "DataType": "string", "Value": "Mapco Express"}, { "MappedFieldName": "Invoice Nbr", "DataType": "string", "Value": "31856174"}, { "MappedFieldName": "Invoice Document Date", "DataType": "DateTime", "Value": "2018-12-25 00:00:00.000"}, { "MappedFieldName": "Processing Date", "DataType": "DateTime", "Value": "2019-01-04 00:00:00.000"}, { "MappedFieldName": "Vendor Name", "DataType": "string", "Value": "Bullseye"}, { "MappedFieldName": "Account Nbr", "DataType": "string", "Value": "0048219"}, { "MappedFieldName": "Location #", "DataType": "string", "Value": "7520"}, { "MappedFieldName": "Amount Invoiced", "DataType": "decimal", "Value": "3580.43"}, { "MappedFieldName": "Amount Processed", "DataType": "decimal", "Value": "3580.43"}, { "MappedFieldName": "Invoice Start Date", "DataType": "DateTime", "Value": "2018-04-01 00:00:00.000"}, { "MappedFieldName": "Invoice End Date", "DataType": "DateTime", "Value": "2018-04-01 00:00:00.000"}]')
声明:
DECLARE @search nvarchar(max) = '004'
SELECT
i.*,
-- You may include the keys and values from the input JSON:
j.*
FROM Invoices i
CROSS APPLY OPENJSON(i.InvoiceData) WITH (
-- You may define only the columns, that you need here:
[MappedFieldName] nvarchar(100) '$.MappedFieldName',
[DataType] nvarchar(20) '$.DataType',
[Value] nvarchar(100) '$.Value'
) j
WHERE j.[Value] LIKE CONCAT('%', @search, '%')
查询可以简单地写成如下。当相应的 JSON 列中有一个或多个匹配项时,它将 return 1 张发票:
SELECT *
FROM invoice
WHERE EXISTS (
SELECT 1
FROM OPENJSON(invoicedata)
WITH (
[Value] NVARCHAR(100) '$.Value'
)
WHERE [Value] LIKE '%' + '004' + '%'
)
我正在为我的应用程序中的搜索字段创建一个查询。该查询使用 "like" 关键字来检查记录中的各种字段。其中一个字段是未命名的 ([{}, {}]) json 数组。数组中的字段全部匹配。我希望能够在不使用索引的情况下检查数组的每个 "Value" 属性,即“$[0].value”。原因是数组的大小可能会有所不同。以下是数据示例:
[{
"MappedFieldName": "Customer",
"DataType": "string",
"Value": "Mapco Express"
}, {
"MappedFieldName": "Invoice Nbr",
"DataType": "string",
"Value": "31856174"
}, {
"MappedFieldName": "Invoice Document Date",
"DataType": "DateTime",
"Value": "2018-12-25 00:00:00.000"
}, {
"MappedFieldName": "Processing Date",
"DataType": "DateTime",
"Value": "2019-01-04 00:00:00.000"
}, {
"MappedFieldName": "Vendor Name",
"DataType": "string",
"Value": "Bullseye"
}, {
"MappedFieldName": "Account Nbr",
"DataType": "string",
"Value": "0048219"
}, {
"MappedFieldName": "Location #",
"DataType": "string",
"Value": "7520"
}, {
"MappedFieldName": "Amount Invoiced",
"DataType": "decimal",
"Value": "3580.43"
}, {
"MappedFieldName": "Amount Processed",
"DataType": "decimal",
"Value": "3580.43"
}, {
"MappedFieldName": "Invoice Start Date",
"DataType": "DateTime",
"Value": "2018-04-01 00:00:00.000"
}, {
"MappedFieldName": "Invoice End Date",
"DataType": "DateTime",
"Value": "2018-04-01 00:00:00.000"
}]
和
SELECT *
FROM [dbo].[Invoice]
WHERE JSON_VALUE(InvoiceData, '$.Value') like '%' + @searchText + '%'
此查询无效,因为我没有指定索引,即“$[0].Value”。
我明白了。我首先在搜索文本过滤器的记录的 json 字段上使用 OPENJSON,以获取找到文本的 json 数组部分的索引。接下来我使用索引where 子句标识要查找的数组索引。处理这个的代码如下。这将 return 在记录 json 数组中找到搜索文本的所有记录。
declare @searchText varchar(200) = '004'
declare @searchIndex varchar(10)
SELECT @searchIndex = [key]
FROM OPENJSON((SELECT InvoiceData FROM [dbo].[Invoice])) where Json_Value(value, '$.Value') like '%' + @searchText + '%'
SELECT *
FROM [dbo].[Invoice]
WHERE JSON_VALUE(InvoiceData, '$[' + @searchIndex +'].Value') like '%' + @searchText + '%'
这个答案可能会被简化。如果你有一个简单的答案,请随意post。
输入JSON
是一个JSON
对象的数组,具有固定结构(MappedFieldName
、DataType
和Value
键),所以另一种可能的方法是将 OPENJSON()
与显式架构一起使用到 return 一个 table 以及您在 WITH
子句中定义的列。使用这种方法,您可以过滤 invoices
table and/or 从输入 JSON
:
Table:
CREATE TABLE Invoices (
InvoiceData nvarchar(max)
)
INSERT INTO Invoices
(InvoiceData)
VALUES
(N'[{ "MappedFieldName": "Customer", "DataType": "string", "Value": "Mapco Express"}, { "MappedFieldName": "Invoice Nbr", "DataType": "string", "Value": "31856174"}, { "MappedFieldName": "Invoice Document Date", "DataType": "DateTime", "Value": "2018-12-25 00:00:00.000"}, { "MappedFieldName": "Processing Date", "DataType": "DateTime", "Value": "2019-01-04 00:00:00.000"}, { "MappedFieldName": "Vendor Name", "DataType": "string", "Value": "Bullseye"}, { "MappedFieldName": "Account Nbr", "DataType": "string", "Value": "0048219"}, { "MappedFieldName": "Location #", "DataType": "string", "Value": "7520"}, { "MappedFieldName": "Amount Invoiced", "DataType": "decimal", "Value": "3580.43"}, { "MappedFieldName": "Amount Processed", "DataType": "decimal", "Value": "3580.43"}, { "MappedFieldName": "Invoice Start Date", "DataType": "DateTime", "Value": "2018-04-01 00:00:00.000"}, { "MappedFieldName": "Invoice End Date", "DataType": "DateTime", "Value": "2018-04-01 00:00:00.000"}]')
声明:
DECLARE @search nvarchar(max) = '004'
SELECT
i.*,
-- You may include the keys and values from the input JSON:
j.*
FROM Invoices i
CROSS APPLY OPENJSON(i.InvoiceData) WITH (
-- You may define only the columns, that you need here:
[MappedFieldName] nvarchar(100) '$.MappedFieldName',
[DataType] nvarchar(20) '$.DataType',
[Value] nvarchar(100) '$.Value'
) j
WHERE j.[Value] LIKE CONCAT('%', @search, '%')
查询可以简单地写成如下。当相应的 JSON 列中有一个或多个匹配项时,它将 return 1 张发票:
SELECT *
FROM invoice
WHERE EXISTS (
SELECT 1
FROM OPENJSON(invoicedata)
WITH (
[Value] NVARCHAR(100) '$.Value'
)
WHERE [Value] LIKE '%' + '004' + '%'
)