如何在mysql中对json而不是table应用where条件?

holgip5t  于 2023-05-16  发布在  Mysql
关注(0)|答案(2)|浏览(197)

我尝试在JSON数据上应用where子句,而不是表和列。我已经尝试了很多方法,但没有得到我想要的结果。
下面是一个查询:

select 
CustomerName as 'CustomerName',
TRUNCATE(JSON_VALUE(BillData, '$[0].due'), 3) as 'Balance'
from 
(
select
CONCAT(cd.FirstName, ' ',cd.LastName) as 'CustomerName',
sb.billData as 'BillData'
from test.customerData cd
inner join test.customerbills sb on cd.customerCode = sb.customerCode
) as tb

BillData是一个json。BillData包含如下数据:

[{
"isPastDue":true,
"isPrinted":true,
"dueDate":"2023-03-28"
},
{
"isPastDue":false,
"isPrinted":true,
"dueDate":"2023-04-22"
},
{
"isPastDue":false,
"isPrinted":false,
"dueDate":"2023-05-06"
}]

现在,我想获取isPastDue和isPrinted标志为false的节点的dueDate。
我花了很多时间来获得适当的数据,但没有找到它。我找到了下面的解决方案,但它不起作用。

(
SELECT JSON_EXTRACT(BillData, '$.dueDate') AS item
WHERE JSON_EXTRACT(BillData, '$.isPrinted') = 'false'
and JSON_EXTRACT(BillData, '$.isPastDue') = 'false'
) as 't1'

接下来,当我运行查询时,结果中显示为null。我怎样才能达到预期的结果?
先谢谢你。

jyztefdp

jyztefdp1#

它看起来像“BillData”是一个对象数组,而您试图访问单个对象。请尝试这种方法:

(
SELECT JSON_EXTRACT(BillData, '$[*].dueDate') AS item
WHERE JSON_EXTRACT(BillData, '$[*].isPrinted') = 'false'
and JSON_EXTRACT(BillData, '$[*].isPastDue') = 'false'
) as 't1'

如果这不起作用,您必须手动遍历数组的索引。

km0tfn4u

km0tfn4u2#

我想获取isPastDue和isPrinted标志为false的节点的dueDate
您可以使用json_table将对象数组转换为表,如下所示:

SELECT *
FROM customerData cd
CROSS JOIN JSON_TABLE(
                       cd.billData,
                      '$[*]' 
                       COLUMNS (
                       isPastDue tinyint PATH '$.isPastDue',
                       isPrinted tinyint PATH '$.isPrinted',
                       dueDate DATE PATH '$.dueDate'
                      ) ) j

所以你的查询可以是这样的:

SELECT CONCAT(cd.FirstName, ' ',cd.LastName) as 'CustomerName', j.*
FROM customerData cd
inner join customerbills sb on cd.customerCode = sb.customerCode
CROSS JOIN JSON_TABLE(
                       cd.billData,
                      '$[*]' 
                       COLUMNS (
                       isPastDue tinyint PATH '$.isPastDue',
                       isPrinted tinyint PATH '$.isPrinted',
                       dueDate DATE PATH '$.dueDate'
                      ) ) j
where isPastDue = 0 and isPrinted = 0

Demo here

相关问题