How to get n1ql query response in a particular format? - couchbase

when i execute below query
SELECT r.name AS organizationRoleName, r.organizationRoleId, a.city, a.zip,a.address1
FROM `contact` AS c
UNNEST c.organizationRoles AS r
UNNEST r.addressAssociations AS aa
jOIN `optima_contact` AS a
ON aa.addressId = TO_NUMBER(a.addressId)
WHERE c.type = "organization" AND a.type = "address" and a.city="Plaridel";
i get the response as below
[
{
"address1": "Ground Floor Waltermart Center-Plaridel, Cagayan Valley Road, Barrio Banga 1, Plaridel",
"city": "Plaridel",
"organizationRoleId": 903,
"organizationRoleName": "SUN - WALTERMART PLARIDEL",
"zip": "3004"
},
{
"address1": "Ground Floor Waltermart Center-Plaridel Cagayan Valley Road Barrio Banga 1 Plaridel",
"city": "Plaridel",
"organizationRoleId": 1001,
"organizationRoleName": "FRS1 Store",
"zip": "3004"
}
]
Is there anyway to get the response in below format instead of above format?
[
{
"organizationRoleId": 903,
"organizationRoleName": "SUN - WALTERMART PLARIDEL",
"storeAddress": {
"address1": "Ground Floor Waltermart Center-Plaridel, Cagayan Valley Road, Barrio Banga 1, Plaridel",
"city": "Plaridel",
"zipCode": "3004"
}
},
{
"organizationRoleId": 1001,
"organizationRoleName": "FRS1 Store",
"storeAddress": {
"address1": "Ground Floor Waltermart Center-Plaridel Cagayan Valley Road Barri Banga
1 Plaridel",
"city": "Plaridel",
"zipCode": "3004"
}
}
]
What should be the way to get the above type of response?

You can construct Object using {city, zip, address1} and Alias AS storeAddress
SELECT r.name AS organizationRoleName, r.organizationRoleId,
{a.city, a.zip,a.address1} AS storeAddress
FROM `contact` AS c
UNNEST c.organizationRoles AS r
UNNEST r.addressAssociations AS aa
jOIN `optima_contact` AS a
ON aa.addressId = TO_NUMBER(a.addressId)
WHERE c.type = "organization" AND a.type = "address" and a.city="Plaridel";

Related

Json query to a table?

I have a JSON string as shown below. How can I create a table below or similar using SQL Server with a procedure or function? Thanks all.
I'm using SQL Server 15.0.2080.9.
{
"Person": {
"firstName": "John",
"lastName": "Smith",
"age": 25,
"Address": {
"streetAddress":"21 2nd Street",
"city":"New York",
"state":"NY",
"postalCode":"10021"
},
"PhoneNumbers": {
"home":"212 555-1234",
"fax":"646 555-4567"
}
}
}
An excellent starting point is this Q&A, but a simplified approach (if the parsed JSON has a variable structure with nested JSON objects, but without JSON arrays) is the folowing recursive statement:
JSON:
DECLARE #json nvarchar(max) = N'
{
"Person": {
"firstName": "John",
"lastName": "Smith",
"age": 25,
"Address": {
"streetAddress":"21 2nd Street",
"city":"New York",
"state":"NY",
"postalCode":"10021"
},
"PhoneNumbers": {
"home":"212 555-1234",
"fax":"646 555-4567"
}
}
}'
Statement:
;WITH rCTE AS (
SELECT
1 AS Id,
CONVERT(nvarchar(max), NULL) COLLATE DATABASE_DEFAULT AS [Parent],
CONVERT(nvarchar(max), N'Person') COLLATE DATABASE_DEFAULT AS [Key],
CONVERT(nvarchar(max), JSON_QUERY(#json, '$.Person')) COLLATE DATABASE_DEFAULT AS [Value]
UNION ALL
SELECT
r.Id + 1,
CONVERT(nvarchar(max), r.[Key]) COLLATE DATABASE_DEFAULT,
CONVERT(nvarchar(max), c.[Key]) COLLATE DATABASE_DEFAULT,
CONVERT(nvarchar(max), c.[value]) COLLATE DATABASE_DEFAULT
FROM rCTE r
CROSS APPLY OPENJSON(r.[Value]) c
WHERE ISJSON(r.[Value]) = 1
)
SELECT [Parent], [Key], [Value]
FROM rCTE
ORDER BY Id
Result:
Parent
Key
Value
Person
{"firstName": "John", "lastName": "Smith", "age": 25, "Address": {"streetAddress":"21 2nd Street", "city":"New York", "state":"NY", "postalCode":"10021"}, "PhoneNumbers": {"home":"212 555-1234", "fax":"646 555-4567" }}
Person
firstName
John
Person
lastName
Smith
Person
age
25
Person
Address
{"streetAddress":"21 2nd Street", "city":"New York", "state":"NY", "postalCode":"10021"}
Person
PhoneNumbers
{"home":"212 555-1234", "fax":"646 555-4567"}
PhoneNumbers
home
212 555-1234
PhoneNumbers
fax
646 555-4567
Address
streetAddress
21 2nd Street
Address
city
New York
Address
state
NY
Address
postalCode
10021
You can use Openjson, it would give you your desired result.
this is an example for your specific JSON:
DECLARE #Json NVARCHAR(max) = '{
"Person": {
"firstName": "John",
"lastName": "Smith",
"age": 25,
"Address": {
"streetAddress":"21 2nd Street",
"city":"New York",
"state":"NY",
"postalCode":"10021"
},
"PhoneNumbers": {
"home":"212 555-1234",
"fax":"646 555-4567"
}
}
}'
SELECT NULL AS Parent
,[KEY]
,[value]
FROM openjson(#json, '$')
UNION ALL
SELECT 'Person' AS Parent,
[KEY]
,[value]
FROM openjson(#json, '$.Person')
UNION ALL
SELECT 'Address'AS Parent,
[KEY]
,[value]
FROM openjson(#json, '$.Person.Address')
UNION ALL
SELECT 'PhoneNumbers' AS Parent ,[KEY]
,[value]
FROM openjson(#json, '$.Person.PhoneNumbers')

correctly reading data from a text file with json format in it

Imagine I have a text file with the following two observations:
liame#ziggo.nl:horse22| homeAddress = {
"city": "AMSTERDAM",
"houseNumber": "5",
"houseNumberAddition": null,
"postalCode": "1111 AN",
"street": "Walker",
"__typename": "ShopperAddress"
}
johndoe#live.nl:pizzalover1 | homeAddress = {
"city": "NEW YOK",
"houseNumber": "23",
"houseNumberAddition": null,
"postalCode": "9999 HV",
"street": "Marie Curie",
"__typename": "ShopperAddress"
}
Is there a way to read in this text file in such a way that the data frame looks like this:
username1 username2 city housenumber housenumber_addition postalcode street typename
liam#ziggo.nl horse22 AMSTERDAM 5 null 1111 AN Walker ShopperAddress
johndoe#live.nl pizzalover1 NEW YORK 23 null 9999 HV Marie Curie ShopperAddress
Thx
Your text file shows that there is a pattern to how the data is encoded:
<username1>:<username2> | homeAddress = {
<json_data>
}
We are going to parse the file in 2 passes: first pass to separate one record
from another and second pass to pick out the fields within a record:
A record ends on a line containing a single "}" character
Use regex to separate the fields inside a record
import json, re
import pandas as pd
data = []
pattern = re.compile(r"(.+?):(.+?)\s*\|\s*homeAddress = (.+)", re.DOTALL)
with open('data.txt') as fp:
record = ""
for line in fp:
record += line
if line == "}\n":
m = pattern.match(record)
if m:
username1 = m.group(1)
username2 = m.group(2)
home_address = json.loads(m.group(3))
data.append({
"username1": username1,
"username2": username2,
**home_address
})
record = ""
df = pd.DataFrame(data).rename(columns={"__typename": "typename"})
You can rework a bit your original text to make it a valid dictionary/JSON and feed it to pandas.read_json:
(pd.read_json('[%s]'%re.sub(r'([^:\n]+):([^\|:]+)\s*\|\s*homeAddress = {',
r',{\n "username1":"\1",\n "username2":"\2",',
text)[1:])
.rename(columns={'houseNumber': 'housenumber',
'houseNumberAddition': 'housenumber_addition',
'postalCode': 'postalcode',
'__typename': 'typename'})
)
output:
username1 username2 city housenumber housenumber_addition postalcode street typename
0 liame#ziggo.nl horse22 AMSTERDAM 5 NaN 1111 AN Walker ShopperAddress
1 johndoe#live.nl pizzalover1 NEW YOK 23 NaN 9999 HV Marie Curie ShopperAddress
intermediate reworked data:
[{
"username1":"liame#ziggo.nl",
"username2":"horse22",
"city": "AMSTERDAM",
"houseNumber": "5",
"houseNumberAddition": null,
"postalCode": "1111 AN",
"street": "Walker",
"__typename": "ShopperAddress"
}
,{
"username1":"johndoe#live.nl",
"username2":"pizzalover1 ",
"city": "NEW YOK",
"houseNumber": "23",
"houseNumberAddition": null,
"postalCode": "9999 HV",
"street": "Marie Curie",
"__typename": "ShopperAddress"
}]

PostgreSQL: Syntax for query nested json array

I've recently discovered the PostgreSQL can be used store JSON
before I import loads of data I need to understand how to retrieve it in particular the nested objects
This postgresql tutorial is a good starting point but doesn't really explain how to query nested json array
In the sample below I need to select the codes -> code where codes -> level: 1 (adminCode1_iso) is related to adminName1 and if it exists codes -> level: 2 is related to adminName2
CREATE TABLE gn_json (
id serial NOT NULL PRIMARY KEY,
info json NOT NULL
);
comment on table gn_json is 'How PG holds json';
insert into gn_json (info)
VALUES ('{
"adminCode2": "C3",
"codes": [
{
"code": "ENG",
"level": "1",
"type": "ISO3166-2"
},
{
"code": "CAM",
"level": "2",
"type": "ISO3166-2"
}
],
"adminCode3": "12UE",
"adminName4": "Yelling",
"adminName3": "Huntingdonshire",
"adminCode1": "ENG",
"adminName2": "Cambridgeshire",
"distance": 0,
"countryCode": "GB",
"countryName": "United Kingdom",
"adminName1": "England",
"adminCode4": "12UE085"
}',
'{
"codes": [
{
"code": "81",
"level": "1",
"type": "ISO3166-2"
}
],
"adminCode1": "63",
"distance": 0,
"countryCode": "TH",
"countryName": "Thailand",
"adminName1": "Krabi"
}');
select info ->> 'countryName' as countryName,info ->> 'countryCode' as countryCode,
info ->> 'adminName1' as adminName1, info ->> 'adminCode1' as adminCode1,
info ->> 'adminName2' as adminName2, info ->> 'adminCode2' as adminCode2,
info ->'codes->0->' -> 'code' as adminCode1_iso,
info ->'codes->1->' -> 'code' as adminCode2_iso
FROM gn_json;
Edit Expected outcome
countryname countrycode adminname1 admincode1 adminname2 admincode2 admincode1_iso admincode2_iso
United Kingdom GB England ENG Cambridgeshire C3 ENG CAM
Thailand TH Krabi 63 NULL NULL 81 NULL

How do I get nested JSON data out of SQLite with a multi-level group by?

create table store (id integer primary key, name text);
create table opening (store integer references store(id),
wday text, start integer, end integer);
insert into store (name) values ('foo'), ('bar');
insert into opening (store, wday, start, end)
values (1, 'mon', 0, 60),
(1, 'mon', 60, 120),
(1, 'tue', 180, 240),
(1, 'tue', 300, 360),
(2, 'wed', 0, 60),
(2, 'wed', 60, 120),
(2, 'thu', 180, 240);
I'm trying to get in a single query all the stores and their respective openings by weekday as JSON.
{
"1": {
"name": "foo",
"openings": {
"mon": [ [ 0, 60 ], [ 60, 120 ] ],
"tue": [ [180, 240 ], [ 300, 360 ] ]
}
},
"2": {
"name": "bar",
"openings": {
"wed": [ [0,60], [60,120] ],
"thu": [ [180,240] ]
}
}
}
Here's the evolution of what I have tried. I missing a way to do multi-level json_group_object I suppose.
select * from opening;
store wday start end
---------- ---------- ---------- ----------
1 mon 0 60
1 mon 60 120
1 tue 180 240
1 tue 300 360
2 wed 0 60
2 wed 60 120
2 thu 180 240
select * from opening group by store;
store wday start end
---------- ---------- ---------- ----------
1 mon 0 60
2 wed 0 60
select json_group_object(store, wday) from opening group by store;
json_group_object(store, wday)
-----------------------------------------
{"1":"mon","1":"mon","1":"tue","1":"tue"}
{"2":"wed","2":"wed","2":"thu"}
select store, wday, json_group_array(json_array(start, end))
from opening group by store, wday;
store wday json_group_array(json_array(start, end))
---------- ---------- ----------------------------------------
1 mon [[0,60],[60,120]]
1 tue [[180,240],[300,360]]
2 thu [[180,240]]
2 wed [[0,60],[60,120]]
select json_object('id', store,
'openings', json_group_object(wday, json_group_array(json_array(start, end)))
) from opening group by store, wday;
Error: near line 17: misuse of aggregate function json_group_array()
select json_object('id', store,
'openings', json_object(wday, json_group_array(json_array(start, end)))
) from opening group by store, wday;
{"id":1,"openings":{"mon":[[0,60],[60,120]]}}
{"id":1,"openings":{"tue":[[180,240],[300,360]]}}
{"id":2,"openings":{"thu":[[180,240]]}}
{"id":2,"openings":{"wed":[[0,60],[60,120]]}}
How can I group on same id here?
A row will be returned for each unique values corresponding to a group by. Thus, the outermost select must have a group by store.
select json_group_object(store, x)
from (
select
store,
json_object(
'id', store,
'openings', json_object(wday, json_group_array(json_array(start, end)))
) x
from opening group by store, wday
) group by store;
This inner query returns literal JSON however. It seems silly to decode the inner JSON just to then encode it all in the outer-most query.
{"1":"{\"id\":1,\"openings\":{\"mon\":[[0,60],[60,120]]}}","1":"{\"id\":1,\"openings\":{\"tue\":[[180,240],[300,360]]}}"}
{"2":"{\"id\":2,\"openings\":{\"thu\":[[180,240]]}}","2":"{\"id\":2,\"openings\":{\"wed\":[[0,60],[60,120]]}}"}
IIRC in Postgres this inner query that returns JSON wouldn't return literal JSON but either way I'm confused how to continue.
Thanks for any help.
Adding an example for general reference. Shawn's point about using json(x) in the outer selects is key. Here's an example with multiple levels of nested arrays
The sample data: select * from tblSmall
region|subregion |postalcode|locality |lat |lng |
------|-------------|----------|-------------------------------|-------|-------|
Delhi |Central Delhi| 110001|Connaught Place |28.6431|77.2197|
Delhi |Central Delhi| 110001|Parliament House |28.6407|77.2154|
Delhi |Central Delhi| 110003|Pandara Road |28.6431|77.2197|
Delhi |Central Delhi| 110004|Rashtrapati Bhawan |28.6453|77.2128|
Delhi |Central Delhi| 110005|Karol Bagh |28.6514|77.1907|
Delhi |Central Delhi| 110005|Anand Parbat |28.6431|77.2197|
Delhi |North Delhi | 110054|Civil Lines (North Delhi) |28.6804|77.2263|
Delhi |North Delhi | 110084|Burari |28.7557|77.1994|
Delhi |North Delhi | 110084|Jagatpur |28.7414|77.2199|
Delhi |North Delhi | 110086|Kirari Suleman Nagar |28.7441|77.0732|
For each region has multiple subregion values, each subregion has multiple postalcode values, and each postalcode has multiple locality values.
Here's the sql :
select json_object('region', A2.region, 'subregions', json_group_array(json(A2.json_obj2))) from
(select A1.region, json_object('subregion',
A1.subregion,
'postalCodes',
json_group_array(json(A1.json_obj1)) ) as json_obj2 from
(select region, subregion, json_object('postalCode',
postalcode,
'localities',
json_group_array(json_object('locality',
locality, 'latitude',
lat, 'longitude', lng) ) ) as json_obj1
from tblSmall where subregion in ('Central Delhi', 'North Delhi')
group by region, subregion, postalcode) as A1
group by A1.region, A1.subregion) as A2
group by A2.region
Note the json(A1.json_obj1) and json(A2.json_obj2) bits to handle the decode/re-encode of json coming out of the inner queries.
Here's the result (kind of long because of pretty-print) - there's a subregions array, which contains a postalcodes array, which contains a localities array:
{
"region": "Delhi",
"subregions": [
{
"subregion": "Central Delhi",
"postalCodes": [
{
"postalCode": 110001,
"localities": [
{
"locality": "Connaught Place",
"latitude": 28.6431,
"longitude": 77.2197
},
{
"locality": "Parliament House",
"latitude": 28.6407,
"longitude": 77.2154
}
]
},
{
"postalCode": 110003,
"localities": [
{
"locality": "Pandara Road",
"latitude": 28.6431,
"longitude": 77.2197
}
]
},
{
"postalCode": 110004,
"localities": [
{
"locality": "Rashtrapati Bhawan",
"latitude": 28.6453,
"longitude": 77.2128
}
]
},
{
"postalCode": 110005,
"localities": [
{
"locality": "Karol Bagh",
"latitude": 28.6514,
"longitude": 77.1907
},
{
"locality": "Anand Parbat",
"latitude": 28.6431,
"longitude": 77.2197
}
]
},
{
"postalCode": 110060,
"localities": [
{
"locality": "Rajender Nagar",
"latitude": 28.5329,
"longitude": 77.2004
}
]
},
{
"postalCode": 110069,
"localities": [
{
"locality": "Union Public Service Commission",
"latitude": 28.5329,
"longitude": 77.2004
}
]
},
{
"postalCode": 110100,
"localities": [
{
"locality": "Foreign Post Delhi IBC",
"latitude": 28.6563,
"longitude": 77.1366
}
]
}
]
},
{
"subregion": "North Delhi",
"postalCodes": [
{
"postalCode": 110054,
"localities": [
{
"locality": "Timarpur",
"latitude": 28.7038,
"longitude": 77.2227
},
{
"locality": "Civil Lines (North Delhi)",
"latitude": 28.6804,
"longitude": 77.2263
}
]
},
{
"postalCode": 110084,
"localities": [
{
"locality": "Burari",
"latitude": 28.7557,
"longitude": 77.1994
},
{
"locality": "Jagatpur",
"latitude": 28.7414,
"longitude": 77.2199
}
]
},
{
"postalCode": 110086,
"localities": [
{
"locality": "Kirari Suleman Nagar",
"latitude": 28.7441,
"longitude": 77.0732
}
]
}
]
}
]
}

SELECT with temporary column with value based on other column

I have mysql table which schema resembles the json array below.
[
{ "id": 1, "firstName": "Charles Montgomery", "lastName": "Burns", "managerId": 12},
{ "id": 2, "firstName": "Bart", "lastName": "Simpson", "managerId": 1},
{ "id": 3, "firstName": "Marge", "lastName": "Simpson", "managerId": 1},
{ "id": 4, "firstName": "Lisa", "lastName": "Simpson", "managerId": 1},
{ "id": 5, "firstName": "Maggie", "lastName": "Simpson", "managerId": 1},
{ "id": 6, "firstName": "Homer", "lastName": "Simpson", "managerId": 4},
{ "id": 7, "firstName": "Ned", "lastName": "Flanders", "managerId": 4},
{ "id": 8, "firstName": "Krusty", "lastName": "The Clown", "managerId": 2},
{ "id": 9, "firstName": "Waylon", "lastName": "Smithers", "managerId": 2},
{ "id": 10, "firstName": "Ralph", "lastName": "Wiggum", "managerId": 5},
{ "id": 11, "firstName": "Itchy", "lastName": "", "managerId": 5},
{ "id": 12, "firstName": "Comic Book Guy", "lastName": "", "managerId": 4}
]
managerId field is self referencing foreign key to the id field.
I need to make a query which will add column on the fly with "managerName" computed from id field which will hold concatenated firstName and lastName.
Below is (simplified) query that I've tried. Question mark is placeholder filled by mysql driver (in nodejs):
SELECT * ,
(SELECT CONCAT_WS(' ', firstName, lastName) FROM employee WHERE managerId = id ) as managerName
FROM employee WHERE employee.id = ?;
I realize this WHERE managerId = id is the place to look, but I honestly don't know what condition to place to match correct values.
Can anyone help?
EDIT
In case someone stumbles upon same thing, I've found helpful article. Even examples are similar.
LEFT JOIN is your friend. tra to use a query like this:
SELECT
e.*,
CONCAT_WS(' ', m.firstName, m.lastName) AS managerName
FROM employee e WHERE e.employee.id = ?
LEFT JOIN employee m ON e.managerId = m.id;