如何在MySQL中在JSON而不是表上应用where条件?

huangapple go评论67阅读模式
英文:

How to apply the where condition on json instead of table in mysql?

问题

I am trying to apply the where clause on json data instead of table and column. I have tried lots of way but didn't get the result as I want.

Below is a query:

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 is a json.BillData contains data like below:

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

Now, I want to get the dueDate of that node which isPastDue and isPrinted flag is false.

I have spend lots of time for get the proper data but didn't found it. I found the solution like below but it's not working.

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

Next when I run the query then it's showing null in the result. How can I achieve the result as per expectation?

Thank you in advance.

英文:

I am trying to apply the where clause on json data instead of table and column. I have tried lots of way but didn't get the result as I want.

Below is a query:

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 is a json.BillData contains data like below:

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

Now, I want to get the dueDate of that node which isPastDue and isPrinted flag is false.

I have spend lots of time for get the proper data but didn't found it. I found the solution like below but it's not working.

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

Next when I run the query then it's showing null in the result. How can I achieve the result as per expectation?

Thank you in advance.

答案1

得分: 1

"BillData" 似乎是一个对象数组,而您试图访问单个对象。请尝试以下方法:

(
SELECT JSON_EXTRACT(BillData, '$[*].dueDate') AS item
WHERE JSON_EXTRACT(BillData, '$[*].isPrinted') = 'false'
and JSON_EXTRACT(BillData, '$[*].isPastDue') = 'false'
) as 't1'
如果这不起作用,您必须手动遍历数组的索引。
英文:

It looks like "BillData" is an array of objects, while you are trying to access a single object.
Please try this approach:

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

If this is not working, you have to go through the indexes of the array manually.

答案2

得分: 0

I want to get the dueDate of that node which isPastDue and isPrinted flag is false:

我想获取那个节点的dueDate,其中isPastDue和isPrinted标志为false。

You can use json_table to convert your array of objects into table as follows:

您可以使用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

So your query can be something like this:

因此,您的查询可以是这样的:

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

英文:

> I want to get the dueDate of that node which isPastDue and isPrinted
> flag is false

You can use json_table to convert your array of objects into table as follows :

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

So your query can be something like this :

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

huangapple
  • 本文由 发表于 2023年5月10日 18:55:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217567.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定