How to select column with json without sending column name? - sql

I'm setting up an API with Node and postgreSQL-node (pg), and when I query for the column in my data base that contains JSON it returns an array of objects with the columns name and the json I want to access.
My current query is:
select jsondata
from breweries
The output is:
[
{
"jsondata": {
"id": 2,
"name": "Avondale Brewing Co",
"brewery_type": "micro",
"street": "201 41st St S",
"city": "Birmingham",
"state": "Alabama",
"postal_code": "35222-1932",
"country": "United States",
"longitude": "-86.774322",
"latitude": "33.524521",
"phone": "2057775456",
"website_url": "http://www.avondalebrewing.com",
"updated_at": "2018-08-23T23:19:57.825Z",
"tag_list": []
}
},
{"jsondata": {...}},
{...}
]
My expectation is to get and array with the contents inside "jsondata" without the name of the column "jsondata", but I can't find a way to access it one level in my query.
Edit:
Here is what I expect:
[
{
"id": 2,
"name": "Avondale Brewing Co",
"brewery_type": "micro",
"street": "201 41st St S",
"city": "Birmingham",
"state": "Alabama",
"postal_code": "35222-1932",
"country": "United States",
"longitude": "-86.774322",
"latitude": "33.524521",
"phone": "2057775456",
"website_url": "http://www.avondalebrewing.com",
"updated_at": "2018-08-23T23:19:57.825Z",
"tag_list": []
},
{...},
{...}
]

I'm not sure what exact output you're expecting, but you can convert the array of dictionaries to rows and then return the jsondata values as individual rows using this:
SELECT jsonb_array_elements(jsondata)->'jsondata'
FROM breweries
Is that along the lines of what you want?
SQL Fiddle

Related

Find authors with age under 40 in my postgresql table

I have the following table with one row. I have tried to query this table to return authors under the age of 40 and have been unable to do so.
CREATE TABLE bookstuff (
data JSON
);
insert into bookstuff(data)
VALUES('
{
"the_books": {
"publishers": [
{
"name": "Dunder Mifflin",
"address": "Scranton, PA",
"country": "USA",
"CEO": "David Wallace"
},
{
"name": "Sabre",
"address": "Tallahassee, FL",
"country": "USA",
"CEO": "Jo Bennett"
},
{
"name": "Michael Scott Paper company",
"address": "Scranton, PA",
"country": "USA",
"CEO": "Michael Gary Scott"
},
{
"name": "Vance Refrigeration",
"address": "Scranton, PA",
"country": "USA",
"CEO": "Bob Vance"
}
],
"authors": [
{
"id": 1,
"name": "Michael Scott",
"age": 45,
"country": "USA",
"agentname": "Jan Levinson",
"books_written": "book1"
},
{
"id": 2,
"name": "Jim Halpert",
"age": 35,
"country": "USA",
"agentname": "Pam Beesly",
"books_written": "book3"
},
{
"id": 3,
"name": "Dwight Schrute",
"age": 40,
"country": "USA",
"agentname": "Angela Martin",
"books_written": "book2"
},
{
"id": 4,
"name": "Pam Halpert",
"age": 35,
"country": "USA",
"agentname": "Angela Martin",
"books_written": "book4"
}
],
"books": [
{
"isbn": "book1",
"title": "The Dundies",
"price": 10.99,
"year": 2005,
"publishername": "Dunder Mifflin"
},
{
"isbn": "book2",
"title": "Bears, Beets, Battlestar Galactica",
"price": 8.99,
"year": 2006,
"publishername": "Dunder Mifflin"
},
{
"isbn": "book3",
"title": "The Sabre Store",
"price": 12.99,
"year": 2007,
"publishername": "Sabre"
},
{
"isbn": "book4",
"title": "Branch Wars",
"price": 14.99,
"year": 2015,
"publishername": "Sabre"
}
]
}
}');
I have tried the following query to get the author's age
SELECT data->'the_books'->'authors'
FROM bookstuff
WHERE (data->'the_books'->'authors'->>'age')::integer > 40;
I expect it to return two values 'Jim halpert' and 'pam halpert' but instead I get no result back, not even null.
I have also tried this query, just to see if i could get anything back at all from the table and still no results:
SELECT data->'the_books'->'authors'
FROM bookstuff
where (data->'the_books'->'authors'->'name')::jsonb ? 'Michael Scott';
I'm new to postgresql, is there a different way I should be going about this?
Using json_array_elements:
select (v -> 'name')#>>'{}' from bookstuff b
cross join json_array_elements(b.data -> 'the_books' -> 'authors') v
where ((v -> 'age')#>>'{}')::int < 40
See fiddle
Another option, slightly more verbose:
select distinct(author->>'name') as author_name from
(select json_array_elements(b.data->'the_books'->'authors') author from bookstuff b) author
where (author->>'age')::int < 40
The distinct might be unnecessary if you really just have one database row and no duplicates in the authors array of that row.
Three considerations of why your final solution doesn't work
where filters out rows - this happens before the 'select'. the row contains everything in this case.
'?' predicate matches an array containing your choosen value "Does the key/element string exist within the JSON value?" You don't have a simple array here array->'key' doesn't pick that attribute into a new array
your select projection isn't called however it was it would contain the whole array (remember where doesn't transform just filters out rows)

Select data from Json array MS SQL Server

I have to select data from Json like this:
[
{
"id": 10100,
"externalId": "100000035",
"name": "Test1",
"companyId": 10099,
"phone": "0738003811",
"email": "test#Test.com",
"mainAddress": {
"county": "UK",
"province": "test",
"zipCode": "01234",
"city": "test",
"street": "test",
"gln": "44,37489331;26,21941193",
"country": {
"iso2": "UK",
"iso3": "UK"
}
},
"active": false,
"main": true,
"stores": [
"Test"
],
"attributes": [
{
"attributeId": 1059,
"attributeName": "CH6 name",
"attributeExternalId": null,
"attributeValueId": 74292,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": null,
"attributePlainValue": "Unknown"
},
{
"attributeId": 1061,
"attributeName": "BD",
"attributeExternalId": null,
"attributeValueId": 81720,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": null,
"attributePlainValue": "Not assigned"
}
],
"daysSinceLastOrder": null
},
{
"id": 62606,
"externalId": "VL_LC_000190",
"name": "Test",
"companyId": 17793,
"phone": "44333424",
"email": "test#email.com",
"mainAddress": {
"firmName": "test",
"county": "test",
"province": "test",
"zipCode": "247555",
"city": "test",
"street": "test",
"gln": "44.8773851;23.9223518",
"country": {
"iso2": "RO",
"iso3": "ROU"
},
"phone": "07547063789"
},
"active": true,
"main": false,
"stores": [
"Valcea"
],
"attributes": [
{
"attributeId": 1042,
"attributeName": "Type of location",
"attributeExternalId": "TYPE_OF_DIVISION",
"attributeValueId": 34506,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": "Small OTC (<40mp)",
"attributePlainValue": "Small OTC (<40mp)"
},
{
"attributeId": 17,
"attributeName": "Limit for payment",
"attributeExternalId": "LIMIT_FOR_PAYMENT_IN_DAYS",
"attributeValueId": 59120,
"attributeValueType": "NUMBER",
"attributeValueEid": null,
"attributePlainValue": "28"
}
],
"daysSinceLastOrder": 147
}
]
I know how to select data from simple json object using "FROM OPENJSON",
but now I have to select a
AttributeValueId, AttributeId and AttributeName, attributePlainValue and CompanyId for each Attribute. So I dont know how to select data from attributes array and then how to join to this CompanyId which is one level up.
Maybe someone knows how write this query.
As mentioned by #lptr in the comments:
You need to pass the result of one OPENJSON to another, using CROSS APPLY. You can select a whole JSON object or array as a property, by using the syntax AS JSON
select
t1.companyid,
t2.*
from openjson(#j)
with (
companyId int,
attributes nvarchar(max) as json
) as t1
cross apply openjson(t1.attributes)
with
(
attributeId int,
attributeName nvarchar(100),
attributeValueId nvarchar(100),
attributePlainValue nvarchar(100)
) as t2;
db<>fiddle
For example, you can use code like this.
f1.metaData->"$.identity.customerID" = '.$customerID.'

Get nested data c.<type>.<type> in SQL Query?

I've been searching everywhere for this seemingly simple action: I'd like to select only a certain few data type from a nested source.
The closest that I can get to the solution is this:
SELECT c.receipt_number, c.millitime, c.email, c.phone, c.shipping, c.shipping_note, c.amount_paid, i.description, i.quantity
FROM c
JOIN i IN c.line_items
WHERE c.millitime > 1627813253000
But this will create lots of duplicated data, like the receipt_number, email, etc in the example:
[
{
"receipt_number": null,
"millitime": 1627813377000,
"email": "test#gmail.com",
"phone": "000000000",
"shipping": {
"address": {
"city": "Sydney",
"country": "AU",
"line1": "Test Street",
"line2": null,
"postal_code": "3000",
"state": "VIC"
},
"name": "New Cust"
},
"shipping_note": "Please knock on door.",
"amount_paid": 104,
"description": "Curry Chicken",
"quantity": 1
},
{
"receipt_number": null,
"millitime": 1627813377000,
"email": "test#gmail.com",
"phone": "000000000",
"shipping": {
"address": {
"city": "Sydney",
"country": "AU",
"line1": "Test Street",
"line2": null,
"postal_code": "3000",
"state": "VIC"
},
"name": "New Cust"
},
"shipping_note": "Please knock on door.",
"amount_paid": 104,
"description": "Chicken Noodle",
"quantity": 8
}
]
Is there a way to create a nested result of c.line_items with just the desired data description and quantity? The final result should be similar to:
[
{
"receipt_number": null,
"millitime": 1627813377000,
"email": "test#gmail.com",
"phone": "000000000",
"shipping": {
"address": {
"city": "Sydney",
"country": "AU",
"line1": "Test Street",
"line2": null,
"postal_code": "3000",
"state": "VIC"
},
"name": "New Cust"
},
"shipping_note": "Please knock on door.",
"amount_paid": 104,
"line_items": [
{
"description": "Chicken Noodle",
"quantity": 8
},
{
"description": "Curry Chicken",
"quantity": 1
}
]
}
]
I have created the same in
You can use distinct keyword to remove duplicates from the results.
Add c.line_items to your select list and change i.description, i.quantity to c.description, c.quantity to add view under line_items.
Query:
SELECT distinct c.receipt_number, c.millitime, c.email, c.phone, c.shipping, c.shipping_note, c.amount_paid, c.line_items
FROM c
JOIN i IN c.line_items
WHERE c.millitime > 1627813253000
Result:
Reference: Azure Cosmos DB SQL query - JSON items

How to get data from json column in mssql

I'm struggling to write a query that gets value from json column with some specific conditions. I have a table named Table1 with a column of type nvarchar(max) named Data that contains some json values. The json itself looks like this:
{
"Addresses": [
{
"ApartmentNumber": "1",
"City": "Rome",
"CountryCode": "IT",
"HouseNumber": "2",
"Post": "Rome",
"PostalCode": "11-111",
"Region": "Rome",
"Street": "Italian",
"StreetPrefix": "St.",
"TypeCode": "PERMANENT"
},
{
"ApartmentNumber": "11",
"City": "Madrid",
"CountryCode": "ES",
"HouseNumber": "22",
"Post": "Madrid",
"PostalCode": "11-111",
"Region": "Madrid",
"Street": "Spanish",
"StreetPrefix": "St.",
"TypeCode": "CORRESPONDENCE"
}
],
"Contacts": [
{
"TypeCode": "EMAIL",
"DefaultContact": false,
"Value": "sample#xyz.com"
}
],
"PersonData": {
"BirthDate": "1968-08-03T00:00:00",
"CitizenshipCode": "US",
"DeathDate": "0001-01-01T00:00:00",
"FirstName": "John",
"Gender": "M",
"LastName": "Jones"
}
}
I would like to get a value of CountryCode from the Addresses node where TypeCode is "CORRESPONDENCE". I tried to achieve that with combinations of JSON_VALUE and JSON_QUERY functions but I failed. Below are some examples of my trials:
query:
SELECT JSON_QUERY(t.Data, '$.Addresses') AS Address FROM [Table1] t
result:
[
{
"ApartmentNumber": "1",
"City": "Rome",
"CountryCode": "IT",
"HouseNumber": "2",
"Post": "Rome",
"PostalCode": "11-111",
"Region": "Rome",
"Street": "Italian",
"StreetPrefix": "St.",
"TypeCode": "PERMANENT"
},
{
"ApartmentNumber": "11",
"City": "Madrid",
"CountryCode": "ES",
"HouseNumber": "22",
"Post": "Madrid",
"PostalCode": "11-111",
"Region": "Madrid",
"Street": "Spanish",
"StreetPrefix": "St.",
"TypeCode": "CORRESPONDENCE"
}
]
or this:
query:
select top 1 JSON_VALUE(t.Data, '$.PersonData.LastName') FROM [Table1] t where ISJSON(t.Data) > 0 and JSON_VALUE(pd.BusinessPartner, '$.PersonData.Gender') = 'F'
result:
"Jones"
but when i to write similar query with Addresses as condition:
query:
select top 1 JSON_VALUE(t.Data, '$.Addresses.CountryCode') FROM [Table1] t where ISJSON(t.Data) > 0 and JSON_VALUE(t.Data,'$.Addresses.TypeCode') = 'CORRESPONDENCE'
I get empty string as the result.
Thanks in advance
From SQL Server 2016, you can query on JSON column. See the documentation : Work with JSON data
The interesting part for you it's Analyze JSON data with SQL queries.
This done :
select Id, PostalCode
from Address
CROSS APPLY OPENJSON (Address.Data, N'$.Addresses')
WITH (
TypeCode varchar(50) '$.TypeCode',
PostalCode varchar(50) '$.PostalCode'
) AS AddressesJsonData
WHERE TypeCode = N'PERMANENT'

Dynamic values in Rest API using JMeter

I have payload POST call:
{
"tenantName":"loki",
"owner":
{
"country": "india",
"firstName": "raj",
"lastName": "kumar",
"locale": "in",
"organization": "softwareag",
"phone": "9789155778",
"title": "mr",
"userName": "raraj#softwareag.com",
"email": "raraj#softwareag.com",
"password":"V2VsY29tZUAxMjM0"
},
"products": [
"cumulocity",
"b2b"
]
}
In that payload, the tenant name is unique, How to pass different values for each post call?
You can use __RandomString to randomize name, for example 5 lower case letters:
${__RandomString(5,abcdefghijklmnopqrstuvwxyz,)}
RandomString function returns a random String of length using characters in chars to use
Or load name values from CSV Data set config
You can use __groovy() function in order to call RandomStringUtils.randomAlphabetic() method like:
${__groovy(org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(4),)}
replace 4 with the number of your choice to make the random string shorter or longer
The function can be inlined directly into your request body
{
"tenantName": "${__groovy(org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(4),)}",
"owner": {
"country": "india",
"firstName": "raj",
"lastName": "kumar",
"locale": "in",
"organization": "softwareag",
"phone": "9789155778",
"title": "mr",
"userName": "raraj#softwareag.com",
"email": "raraj#softwareag.com",
"password": "V2VsY29tZUAxMjM0"
},
"products": [
"cumulocity",
"b2b"
]
}
More information: Apache Groovy - Why and How You Should Use It