I have a SQL 2016 table that contains a column holding JSON data. A sample JSON document looks as follows:
{
"_id": "5a450f0383cac0d725cd6735",
"firstname": "Nanette",
"lastname": "Mccormick",
"registered": "2016-07-10T01:50:10 +04:00",
"friends": [
{
"id": 0,
"name": "Cote Collins",
"interests": [
"Movies",
"Movies",
"Cars"
]
},
{
"id": 1,
"name": "Ratliff Ellison",
"interests": [
"Birding",
"Birding",
"Chess"
]
},
{
"id": 2,
"name": "William Ratliff",
"interests": [
"Music",
"Chess",
"Software"
]
}
],
"greeting": "Hello, Nanette! You have 4 unread messages.",
"favoriteFruit": "apple"
}
I want to pull all documents in which the interests array of each friends object contains a certain value. I attempted this but got no results:
Select *
From <MyTable>
Where 'Chess' IN (Select value From OPENJSON(JsonValue, '$.friends.interests'))
I should have gotten several rows returned. I must not be referencing the interests array correctly or not understanding how SQL Server deals with a JSON array of this type.
Since Interests is a nested array, you need to parse your way through the array levels. To do this, you can use CROSS APPLY with OPENJSON(). The first CROSS APPLY will get you the friend names and the JSON array of interests, and then the second CROSS APPLY pulls the interests out of the array and corrolates them with the appropriate friend names. Here's an example query:
Select [name]
From #MyTable
CROSS APPLY OPENJSON(JsonValue, '$.friends')
WITH ([name] NVARCHAR(100) '$.name',
interests NVARCHAR(MAX) AS JSON)
CROSS APPLY OPENJSON(interests)
WITH (Interest NVARCHAR(100) '$')
WHERE Interest = 'Chess'
Related
I am building a .net core web api using Dapper and Oracle 19c. The application will receive a POST request similar to the one below, and needs to return a value (Salary) from the same table. It needs to loop over the JSON and return the salary filtering on name, id, and year that match relational data in an Employees table which also contains the salary and other information for each employee. I am new to Oracle and especially working with JSON. I tried to use JSON_TABLE, but can't get that to work. What is an easy way to do this?
Request
POST
{
"Employees": [
{
"EMPLOYEE_ID": "100",
"FIRST_NAME":"Steven",
"LAST_NAME": "King",
"HIRE_DATE": "17-JUN-03"
},
{
"EMPLOYEE_ID": "101",
"FIRST_NAME":"Neena",
"LAST_NAME": "Kochar",
"HIRE_DATE": "21-SEP-05"
},
{
"EMPLOYEE_ID": "104",
"FIRST_NAME":"Bruce",
"LAST_NAME": "Ernst",
"HIRE_DATE": "21-MAY-07"
}
]
}
Response
{
"Employees": [
{
"SALARY": "100000",
"STATUS":"SUCCESS"
},
{
"SALARY": "100000",
"STATUS":"SUCCESS"
},
{
"SALARY": "100000",
"STATUS":"SUCCESS"
}
]
}
I tried something like the below query and get "column ambiguously defined" error at line 2 Column 8.
I've tried some other variations of this, but I think I'm using JSON_TABLE wrong and maybe trying to do something that can't be done with JSON functions in Oracle 19c. I'm not sure of the best way to approach this and having trouble making sense of the Oracle documentation and articles. I'm also kind of new with APIs, but can easily do a simple GET request to this table with Dapper and return employee information in JSON.
SELECT *
FROM EMPLOYEES e
JOIN EMPLOYEES e ON e.EMPLOYEE_ID IN(
SELECT jt.* FROM JSON_TABLE(
'{
"Payees": [
{
"EMPLOYEE_ID": "100",
"FIRST_NAME":"Steven",
"LAST_NAME": "King",
"HIRE_DATE": "17-JUN-03"
}
]
},
'COLUMNS(EMPLOYEE_ID VARCHAR2(20) PATH '$.EMPLOYEE_ID')) AS jt
);
Final solution:
select e.salary FROM EMPLOYEES e WHERE e.EMPLOYEE_ID IN (SELECT jt.* FROM JSON_TABLE( q'~{ "Payees": [ { "EMPLOYEE_ID": "100", "FIRST_NAME":"Steven", "LAST_NAME": "King", "HIRE_DATE": "17-JUN-03" } ] }~', '$.Payees[*]' COLUMNS(EMPLOYEE_ID VARCHAR2(20) PATH '$.EMPLOYEE_ID')) AS jt) ;
This is my JSON array object saved in a column
{
"relationalKeys": [
{
"job_type": [
"8",
"5"
],
"job_speciality": [
"50",
"51"
],
"job_department": [
"70",
"71"
],
"job_grade": [
],
"job_work_pattern_id": [
"43"
],
"pay_band_id": [
"31"
],
"staff_group_id": [
"27"
]
}
]
}
I want to extract records matching with such as Jobtype in (8,5). Problem is that when we use CROSS APPLY in a huge database, results are returned very slowly.
This is my query and its working fine, however I want to know if there any solution available to find values without referring to a particular array index i.e [0] but value can exist in anywhere in the json array.
SELECT Json_Value(jsonData, '$.relationalKeys[0].job_type[0]'), *
FROM tbl_jobs_details_v2
WHERE Json_Value(jsonData, '$.relationalKeys[0].job_type[0]') IN (8, 5)
I want something matching in all elements of an array like adding a * but SQL Server doesn't support this.
SELECT Json_Value(jsonData, '$.relationalKeys[0].job_type[*]'),*
FROM tbl_jobs_details_v2
WHERE Json_Value(jsonData, '$.relationalKeys[0].job_type[*]') IN (8, 5)
In my DB I have a column storing JSON. The JSON looks like this:
{
"views": [
{
"id": "1",
"sections": [
{
"id": "1",
"isToggleActive": false,
"components": [
{
"id": "1",
"values": [
"02/24/2021"
]
},
{
"id": "2",
"values": []
},
{
"id": "3",
"values": [
"5393",
"02/26/2021 - Weekly"
]
},
{
"id": "5",
"values": [
""
]
}
]
}
]
}
]
}
I want to create a migration script that will extract a value from this JSON and store them in its own column.
In the JSON above, in that components array, I want to extract the second value from the component with an ID of "3" (among other things, but this is a good example). So, I want to extract the value "02/26/2021 - Weekly" to store in its own column.
I was looking at the JSON_VALUE docs, but I only see examples for specifing indexes for the json properties. I can't figure out what kind of json path I'd need. Is this even possible to do with JSON_VALUE?
EDIT: To clarify, the views and sections components can have static array indexes, so I can use views[0].sections[0] for them. Currently, this is all I have with my SQL query:
SELECT
*
FROM OPENJSON(#jsonInfo, '$.views[0].sections[0]')
You need to use OPENJSON to break out the inner array, then filter it with a WHERE and finally select the correct value with JSON_VALUE
SELECT
JSON_VALUE(components.value, '$.values[1]')
FROM OPENJSON (#jsonInfo, '$.views[0].sections[0].components') components
WHERE JSON_VALUE(components.value, '$.id') = '3'
I have a table with a data_type of json that I need to query one of the properties inside of it.
This is what the data in the column looks like:
{
"id": 7008,
"access_links": [
{
"product_code": "PRODUCT-1",
"link": "https://some.url"
},
{
"product_code": "PRODUCT-2",
"link": "https://someOther.url"
}
],
"library_id": "2d1203db-75b3-43a5-947c-8555b48371db"
}
I need to be able to pull out and filter by the product_code nested inside of the access_links.
I can get one layer deep by using this query:
SELECT
courses.course_metadata -> 'access_links' as access_links
FROM
courses
This seems to get me into the column, but I can't query any further.
The output I receive from the query looks like:
[{"product_code":"PRODUCT-1","link":"https://some.url"},{"product_code":"PRODUCT-2","link":"https://someOther.url"}]
I've tried using the ->> and #>> operators, but they both complain about the array not starting with a {. Also worth noting that the column is a data type of JSON not JSONB, so the #> operator doesn't work.
What am I missing here?
Does this help?
select
json_array_elements (x->'access_links')->'product_code' as product_code
from
(select '{
"id": 7008,
"access_links": [
{
"product_code": "PRODUCT-1",
"link": "https://some.url"
},
{
"product_code": "PRODUCT-2",
"link": "https://someOther.url"
}
],
"library_id": "2d1203db-75b3-43a5-947c-8555b48371db"
}'::json x
) as v
;
product_code
"PRODUCT-1"
"PRODUCT-2"
I have a table with 1 JSON type column city in a MySQL database that stores a JSON array of city objects with following structure:
{
"cities": [
{
"id": 1,
"name": "Mumbai",
"countryID": "9"
},
{
"id": 2,
"name": "New Delhi",
"countryID": "9"
},
{
"id": 3,
"name": "Abu Dhabi",
"countryID": "18"
}
]
}
I want to select objects from the cities array having countryID = 90 but I am stuck as the array of objects is stored in a single column city which is preventing me from doing a (*) with WHERE JSON_CONTAINS(city->'$.cities', JSON_OBEJECT('countryID', '90')).
My query looks like this and I am not getting anywhere,
SELECT JSON_EXTRACT(city, '$.cities') FROM MyTable WHERE JSON_CONTAINS(city->'$.cities', JSON_OBJECT('countryID', '90'))
It'd be a great help if someone can point me in right direction or gimme a solution to this.
Thanks
If you are using MySQL 8.0, there is a feature called JSON table functions. It converts JSON data into tabular form.Then onward you can filter the result.
The query to acheive the same is given below
Select country
FROM json_cal,
JSON_TABLE(
city,
"$.cities[*]" COLUMNS(
country JSON PATH "$",
NESTED PATH '$.countryID' COLUMNS (countryID TEXT PATH '$')
)
) AS jt1
where countryID = 90;
The DB Fiddle can be found here
More information on JSON Table functions can be found here