Selecting all objects in a json array that meet criteria in mysql - mysql

I need to capture rows when data inside a json field in mysql meets certain criteria. What select would I run to get the rows returned where the json column had a Status value of 1000 in any object in the array?
I tried using the something like this:
SELECT * FROM table WHERE Task_JSON->"$[0]" = 1000;
I'm using Server version: 5.7.11 of mysql
[
{
"Sequence":"1" ,
"Status":"1000"
},
{
"Sequence":"2" ,
"Status":"1000"
},
{
"Sequence":"3" ,
"Status":"3000"
}
]

You can use the following solution using JSON_CONTAINS:
SELECT *
FROM table_name
WHERE JSON_CONTAINS(Task_JSON, '{"Status":"1000"}') > 0;
Another solution using JSON_SEARCH:
SELECT *
FROM table_name
WHERE JSON_SEARCH(Task_JSON, 'one', '1000', NULL, '$[*]."Status"') IS NOT NULL;
demo: https://www.db-fiddle.com/f/3JTQreVi63FS7HbmWQ9TEM/4

SELECT * FROM table WHERE Task_JSON ->>'Status' = 1000;

JSON_EXTRACT can help you.
https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html
select * from table where JSON_EXTRACT(Task_JSON, '$.Status') = 1000 ;

Related

JSON data search in MySQL query

I have a MySQL column with below data:
{
"ids": [
"c9cfdecc-dfce-11eb-8c94-0ad691f61ea0",
"c9cfdecc-dfce-11eb-8c94-0ad691f61ea1",
"c9cfdecc-dfce-11eb-8c94-0ad691f61ea2"
]
}
How can I get records that matched with any requested string?
I tried below queries but no use:
SELECT * from test WHERE JSON_CONTAINS(fragments, '"c9cfdecc-dfce-11eb-8c94-0ad691f61ea1"', '$')
SELECT * from test WHERE JSON_CONTAINS(fragments, '"c9cfdecc-dfce-11eb-8c94-0ad691f61ea1"')
SELECT * from test WHERE JSON_SEARCH(fragments, 'one', "c9cfdecc-dfce-11eb-8c94-0ad691f61ea1")

Select keys with boolean value true in PostgreSQL json query

In my PostgreSQL 11.6 table I have a json field app_settings with data on the following format:
{
"my_app": {
"features": {
"very_good_feature": true,
"awesome_feature": false,
"even_better_feature": true
}
}
}
I want to create a query that selects a list of feature names where the feature has the value true. So in the example above, I would like the result of the query simply to be 2 rows like this:
very_good_feature
even_better_feature
I can successfully select ALL the keys with the following query:
select
json_object_keys(app_settings ->'my_app' -> 'features') as k
from
my_table;
How can I write the where clause to only list the ones with true as value?
try with json_each_text:
select j.* from my_table
join lateral json_each_text(app_settings->'my_app'->'features') j(k, v) on true
where
j.v = 'true'

Find match item in JSON array

I have a SQL table called 'Interactions' and a column called Events that holds an array of JSON data. I am looking for any row where the Events json has any array with #odata.type = #Sitecore.XConnect.Goal
[
{
"#odata.type":"#Sitecore.XConnect.Collection.Model.PageViewEvent",
"CustomValues":[
],
"DefinitionId":"9326cb1e-cec8-48f2-9a3e-91c7dbb2166c",
"ItemId":"5ae02a76-ac59-4dbb-913f-3b2e51d92bae",
"Id":"b067f72f-1d60-4773-a2e8-9d23770fea54",
"Timestamp":"2019-11-11T17:18:31.2206225Z",
"ItemLanguage":"en",
"ItemVersion":1,
"Url":"/renewal-confirmation",
"SitecoreRenderingDevice":{
"Id":"fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3",
"Name":"Default"
}
},
{
"#odata.type":"#Sitecore.XConnect.Goal",
"CustomValues":[
],
"DataKey":"/sitecore/content/Client/home/renewal-confirmation",
"DefinitionId":"c0bc91b9-b5fc-4faa-bc12-3dba8bbae44f",
"ItemId":"5ae02a76-ac59-4dbb-913f-3b2e51d92bae",
"EngagementValue":100,
"Id":"e7031fb4-ce57-459f-a9f1-2682748d3431",
"ParentEventId":"b067f72f-1d60-4773-a2e8-9d23770fea54",
"Timestamp":"2019-11-11T17:18:31.2518732Z"
}
]
What I am currently trying is this, but no results
select *
from [Interactions] I
where exists
(
select *
from openjson(I.Events,'$."#odata.type"')
where value = '#Sitecore.XConnect.Goal'
)
If I use this, I can get any row where the 1st item in the array #odata.type = #Sitecore.XConnect.Goal. This works. But I want it from any item in the array.
SELECT *
FROM [Interactions]
WHERE JSON_VALUE([Events], '$[0]."#odata.type"') = '#Sitecore.XConnect.Goal'
One possible approach is to parse the JSON column using OPENJSON() with explicit schema (WITH clause with columns definitions). With this approach you can filter the Interactions table and get information from the JSON data.
Table:
CREATE TABLE Interactions (
Events nvarchar(max)
)
INSERT INTO Interactions
(Events)
VALUES
(N'[
{
"#odata.type":"#Sitecore.XConnect.Collection.Model.PageViewEvent",
"CustomValues":[
],
"DefinitionId":"9326cb1e-cec8-48f2-9a3e-91c7dbb2166c",
"ItemId":"5ae02a76-ac59-4dbb-913f-3b2e51d92bae",
"Id":"b067f72f-1d60-4773-a2e8-9d23770fea54",
"Timestamp":"2019-11-11T17:18:31.2206225Z",
"ItemLanguage":"en",
"ItemVersion":1,
"Url":"/renewal-confirmation",
"SitecoreRenderingDevice":{
"Id":"fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3",
"Name":"Default"
}
},
{
"#odata.type":"#Sitecore.XConnect.Goal",
"CustomValues":[
],
"DataKey":"/sitecore/content/Client/home/renewal-confirmation",
"DefinitionId":"c0bc91b9-b5fc-4faa-bc12-3dba8bbae44f",
"ItemId":"5ae02a76-ac59-4dbb-913f-3b2e51d92bae",
"EngagementValue":100,
"Id":"e7031fb4-ce57-459f-a9f1-2682748d3431",
"ParentEventId":"b067f72f-1d60-4773-a2e8-9d23770fea54",
"Timestamp":"2019-11-11T17:18:31.2518732Z"
}
]')
Statement:
SELECT *
FROM Interactions i
CROSS APPLY OPENJSON(i.Events) WITH (
ODataType nvarchar(100) '$."#odata.type"'
-- and additional columns definitions
) j
WHERE j.ODataType = '#Sitecore.XConnect.Goal'
Your original query is close but doesn't work because you can't directly pick out scalars with OPENJSON. You want something like this:
SELECT *
FROM [interactions]
WHERE EXISTS (
SELECT 1
FROM OPENJSON([events]) WITH (
[#odata.type] NVARCHAR(MAX)
)
WHERE [#odata.type] = '#Sitecore.XConnect.Goal'
)

MySQL JSON - SELECT WHERE

I'm trying to SELECT objects base on the roles property values.
Example: Select all names where role is 1 //response would return danny
Query Statement:
SELECT JSON_EXTRACT(username,'$[*].name') FROM objects WHERE JSON_CONTAINS(username,'1','$[*].roles')
COLUMN: username (JSON)
[
{
"name":"jordan",
"roles":[1,2,5]
},
{
"name":"danny",
"roles":[1,4]
}
]
Question: Why isn't my statement returning just the first object containing the name danny?
Try the following:
SELECT *
FROM objects
WHERE JSON_CONTAINS(components, '1', '$.roles');

MYSQL & C#: How to escape the elements in a SELECT WHERE IN (...) clause?

I have procedure with a single string parameter to retrieve records from my table test which has two fields id(int) and Name(varchar).
the query in the procedure is shown below
Select * from test where id in (strParam);
and value in the parameter will be
strParam="1,2";
but the result will be wrong because query will be as shown below
Select * from test where id in ('1,2');
but i need the query to be like shown below
Select * from test where id in (1,2);
please help me with a solution
the programming language is C#
thanks,
suraj
Usually you construct the SQL correctly in your programming language:
Select * from test where id in ('1,2');
should come from your application code, where it's easier to change strParam="1,2"; to strParam="'1','2'":
Split (explode) the string into an array
escape each element in the array (using the correct MySQL-ESCAPE function)
Join (implode) the array back into a string,
If you really can't change the application code, maybe some SQL tricks could work. Try:
SELECT * FROM test where FIND_IN_SET(ID,strParam) > 0
Not sure if this is the most efficient way:
Explode the value strParam to an array and then build up the string you need in the query:
<?php
$arrayParam = explode(',', $strParam);
$strParamQuery = '(';
foreach ($arrayParam as $Param) {
if ($strParamQuery != '(') { $strParamQuery = $strParamQuery.','; //Add a comma to all but the first occurence
$strParamQuery = $strParamQuery.$param;
}
$strParamQuery = $strParamQuery.')';
$query = 'Select * from test where id in '.$strParamQuery.';';
?>