SQL Server - JSON type enumeration - sql

Given
declare #json varchar(max)='{
"name":"John",
"age":30,
"cars": [
{ "make":"Ford", "models":[ "Fiesta", "Focus", "Mustang","Vintage"] ,"price":[1100,200,300,999]},
{ "make":"BMW", "models":[ "320", "X3", "X5" ] },
{ "make":"Fiat", "models":[ "500", "Panda" ] }
] }';
The query
select * from openjson(#json,'$')
returns 3 columns:
key value type
I haven't found an enumeration of the type column values and their corresponding meaning.
Please point me in the right direction; thanks.

From the MSDN page for OPENJSON:
Value of the Type column JSON data type
0 null
1 string
2 int
3 true/false
4 array
5 object

Related

Creating NUMERIC array from JSONB data in Postgres

I have a Postgres JSONB data which contains an ARRAY of type NUMERIC. I want to extract this ARRAY and store it in a variable of type NUMERIC[]. Here's is my JSONB object.
{
"userIds": [
101,102,103
],
"userRole": {
"id": "1",
"name": "Administrator"
}
}
How can I extract userIds from this JSONB object and store them in NUMERIC[] as I have to iterate on this NUMERIC[]?
Any help would be highly appreciated.
One way is to extract the ids with jsonb_array_elements, parse them to the right data type and aggregate them again in an array, e.g.:
SELECT array_agg(id) FROM (
SELECT
(jsonb_array_elements('{
"userIds": [101,102,103],
"userRole": {
"id": "1",
"name": "Administrator"
}
}'::jsonb->'userIds')::numeric)) j(id);
array_agg
---------------
{101,102,103}
(1 row)
If you want to iterate over these values as rows in your resultset, don't bother with the outer query:
SELECT
jsonb_array_elements('{
"userIds": [101,102,103],
"userRole": {
"id": "1",
"name": "Administrator"
}}'::jsonb->'userIds')::numeric;
jsonb_array_elements
----------------------
101
102
103
(3 rows)

Extract object and scalar value via single function

I have to write a query in SQL to extract a JSON path's value. Now the issue is that path's ultimate value can either be a JSON object or scalar value. But in SQL Server, to get the object and scalar value JSON_QUERY and JSON_VALUE functions should be used respectively. My issue is that I want to write the same query which returns both types of values. Is there any way in which this can be achieved?
You can use OPENJSON function to get the values for a given path $.foo.bar like so:
CREATE TABLE t(
id INT IDENTITY NOT NULL PRIMARY KEY,
json VARCHAR(MAX)
);
INSERT INTO t(json) VALUES
('{ "foo": { "bar": 123 } }'),
('{ "foo": { "bar": "x" } }'),
('{ "foo": { "bar": [1] } }'),
('{ "foo": { "bar": { "baz": 1 } } }');
SELECT *
FROM t
CROSS APPLY OPENJSON(json, '$.foo')
WHERE [key] = 'bar';
The result will contain these important columns:
key: name of the key below $.foo which could be used inside WHERE clause
value: the value for the key having datatype = NVARCHAR(MAX)
type: the type of the value having datatype = INT (see documentation)
Demo on db<>fiddle

MSSQL Query JSON displays Null value

I have a table PublicRelations with a column called Students in a SQL Server database called Subjects.
[
{ "Label": "Name", "ColumnValue": "Trudie" },
{ "Label": "Class", "ColumnValue": "PublicRelations" },
{ "Label": "Room", "ColumnValue": "8049" },
{ "Label": "HttpPath", "ColumnValue": "https://www.google.com/" }
]
I only get NULL when I run the below query using the Json_value. I'd like to get it to display the value from the array. I believe this may have to do with the 4000 character limit?
SELECT [StuduentID],
[Students],
--JSON_VALUE([Students],'$.ColumnValue') AS Name --Only returns NULL
FROM [Subjects].[dbo].[PublicRelations] c
CROSS APPLY OPENJSON(c.Students)
WITH ( Name int '$.Name',
Value nvarchar(255) '$.ColmunValue'
) AS jsonValues
WHERE jsonValues.ColumnValue = 'Trudie'
The query works and I can find what I need, but again, I only get NULL when I want to display that part of the JSON column in my results.
The statement is wrong and you has the following issues (as #MartinSmith already mentioned):
Syntax error - '$.ColmunValue' should be '$.ColumnValue'.
Wrong schema definition (the WITH clause) - I can't see Name key in the input JSON.
Wrong use of JSON_VALUE() - this function extracts scalar value from a JSON string, so JSON_VALUE([Students],'$.ColumnValue') returns NULL with this JSON input in lax mode.
You may try with the following statement (based on the statement in the question):
Table:
CREATE TABLE PublicRelations (
StudentID int,
Students nvarchar(1000))
INSERT INTO PublicRelations (StudentID, Students)
VALUES (1, N'[
{ "Label": "Name", "ColumnValue": "Trudie" },
{ "Label": "Class", "ColumnValue": "PublicRelations" },
{ "Label": "Room", "ColumnValue": "8049" },
{ "Label": "HttpPath", "ColumnValue": "https://www.google.com/" }
]')
Statement:
SELECT p.StudentID, j.*
FROM [PublicRelations] p
CROSS APPLY OPENJSON(p.Students) WITH (
Name nvarchar(50) '$.Label',
Value nvarchar(255) '$.ColumnValue'
) j
WHERE EXISTS (
SELECT 1
FROM OPENJSON(p.Students) WITH (Value nvarchar(255) '$.ColumnValue')
WHERE Value = N'Trudie'
) AND (j.Name IN ('Name', 'Class', 'Room'))
Result:
StudentID Name Value
1 Name Trudie
1 Class PublicRelations
1 Room 8049

SQL Server query JSONobject to get aggregated values

I have a JSON object stored in SQL Server, in a nvarchar(max) column. The JSON looks like this:
{
"data": [{
"RespID": 3512,
"ObsPriceValue": 2.34
}, {
"RespID": 4904,
"ObsPriceValue": 2.54
}, {
"RespID": 5127,
"ObsPriceValue": 3.44
}]
}
The above example array is made up of three items, but I don't know how many items are present in the record, and they can be 2 as well as up to 30.
Each row in the table has an object like the above.
I'd like to get, in a single query, the average value of the field ObsPriceValue
I've tried with JSON_QUERY, but I have always to specify the index of the element.
Is there a way to get it or the JSON schema the data is stored is wrong?
Next approach may help. You need to use OPENJSON() with explicit schema definition to return a table with ObsPriceValue column:
JSON:
DECLARE #json nvarchar(max) = N'{"data": [{
"RespID": 3512,
"ObsPriceValue": 2.34
}, {
"RespID": 4904,
"ObsPriceValue": 2.54
}, {
"RespID": 5127,
"ObsPriceValue": 3.44
}]
}'
Statement:
SELECT AVG(ObsPriceValue) AS AvgObsPriceValue
FROM OPENJSON(#json, '$.data') WITH (
ObsPriceValue numeric(10, 2) '$.ObsPriceValue'
) j
Output:
----------------
AvgObsPriceValue
----------------
2.773333

How to get each JSON child of an array, postgreSQL

I have postgreSQL 9.3 and working with json, my field json in DB looks like:
{
"route_json": [
{
"someKeys": "someValues",
"time": 123
},
{
"someKeys": "someValues",
"time": 123
}, ... N
]
}
In my case I need to catch the 'time' element from each element of route_json array and set them in new array. Is there any way to do this.
It’s not pretty:
SELECT
value->'time'
FROM
json_array_elements('{"route_json": [{"someKeys": "someValues","time": 123},{"someKeys": "someValues","time": 456}]}'::json->'route_json');