How to create hierarchal json object using ltree query results? (postgresql) - sql

I'm trying to create a storage system for custom categories using postgres.
After looking around for potential solutions I settled on trying to use ltree;
Here is an example of raw data below;
+----+---------+---------------------------------+-----------+
| id | user_id | path | name |
+----+---------+---------------------------------+-----------+
| 1 | 1 | root.test | test |
| 2 | 1 | root.test.inbox | inbox |
| 3 | 1 | root.personal | personal |
| 4 | 1 | root.project | project |
| 5 | 1 | root.project.idea | idea |
| 6 | 1 | root.personal.events | events |
| 7 | 1 | root.personal.events.janaury | january |
| 8 | 1 | root.project.objective | objective |
| 9 | 1 | root.personal.events.february | february |
| 10 | 1 | root.project.objective.january | january |
| 11 | 1 | root.project.objective.february | february |
+----+---------+---------------------------------+-----------+
I thought that it might be easier to first order the results, and remove the top level from the path return. Using;
select id, name, subpath(path, 1) as path, nlevel(subpath(path, 1)) as level from testLtree order by level, path
I get;
+----+-----------+----------------------------+-------+
| id | name | path | level |
+----+-----------+----------------------------+-------+
| 3 | personal | personal | 1 |
| 4 | project | project | 1 |
| 1 | test | test | 1 |
| 6 | events | personal.events | 2 |
| 5 | idea | project.idea | 2 |
| 8 | objective | project.objective | 2 |
| 2 | inbox | test.inbox | 2 |
| 9 | february | personal.events.february | 3 |
| 7 | january | personal.events.january | 3 |
| 11 | february | project.objective.february | 3 |
| 10 | january | project.objective.january | 3 |
+----+-----------+----------------------------+-------+
I'm hoping to be able to transform this result into a set of JSON data somehow. I would like an output similar to this;
personal: {
id: 3,
name: 'personal',
children: {
events: {
id: 6,
name: 'events',
children: {
january: {
id: 7,
name: 'january',
children: null
},
february: {
id: 9,
name: 'february',
children: null
}
}
}
}
},
project: {
id: 4,
name: 'project',
children: {
idea: {
id: 5,
name: 'idea',
children: null
},
objective: {
id: 8,
name: 'objective',
children: {
january: {
id: 10,
name: 'january',
children: null
},
february: {
id: 11,
name: 'february',
children: null
}
}
}
}]
},
test: {
id: 1,
name: 'test',
children: {
inbox: {
id: 2,
name: 'inbox',
children: null
}
}
}
I've been looking around for the best way to do this but haven't came across any solutions that make sense to me. However, as I am new to postgres and SQL in general this is expected.
I think I may have to use a recursive query? I'm a bit confused over what the best method/execution of this would be. Any help/advice is much appreciated! and any further questions please ask.
I've put everything into a sqlfiddle below;
http://sqlfiddle.com/#!17/1713e/5

I ran into the same problem as you. I had a large struggle with this in PostgreSQL and it became overly complex to solve. Since I'm using Django (Python framework), I decided to solve it using Python. In case it can help anyone in my same situation, I would like to share the code:
https://gist.github.com/eherrerosj/4685e3dc843e94f3ef8645d31dbe490c

Related

How can I get data from joined tables using fetchxml

I have two tables Tasks and Notes
Tasks
| Id | Task |
|----|------|
| 1 | task1|
| 2 | task2|
| 3 | task3|
Notes
| Id | TaskId | Text |
|----|--------|------|
| 1 | 1 | text1|
| 2 | 1 | text2|
| 3 | 1 | text3|
| 4 | 2 | text4|
| 5 | 2 | text5|
| 6 | 3 | text6|
I want the result of the fetchxml to be:
[ {Id: 1, Task: "task1", Notes: ["text1", "text2", "text3"]},{Id: 2, Task: "task2", Notes: ["text4", "text5"]},{Id: 3, Task: "task3", Notes: ["text6"]}]
I know how to do it using SQL, struggling to find any help to do it using fetchxml
can anyone please help me?
SELECT n.TaskId as Id,t.Task,
group_concat(n.Text) end AS Notes
FROM tasks t,notes n
On t.Id=n.TaskId
WHERE
group by n.TaskId,t.Task
I am writing fetchxml below
Select
n.TaskId as [#id],
t.Task as [#Task],
(
Select
group_concat(n.Text) as [#Notes],
FROM tasks t,notes n
On t.Id=n.TaskId
WHERE
group by n.TaskId,t.Task
FOR XML Raw('notes'),TYPE
)
FROM tasks t
WHERE
group by t.Id,t.Task
FOR XML PATH('tasks'),
ROOT('myFetchXml')

Transform DataFrame to list of dictionaries where column name is a value of key:value pair

I have a panda DataFrame as follow
|---------------------|------------------|------------------|
| A | B | C |
|---------------------|------------------|------------------|
| abc | 34 | 8 |
|---------------------|------------------|------------------|
| abc | | 12 |
|---------------------|------------------|------------------|
| abc | 6 | 321 |
|---------------------|------------------|------------------|
I would like to conver it to a list of dictionary like this:
[
{
name: "A",
value: "abc"
},
{
name: "B",
value: 34
},
{
name: "C",
value: 8
}
]
There are several way to do it with a lot of data manipulation but I am looking for one that is straightforward if it exists
Thank you for your help
[[{'name':k, 'value':v} for k,v in x.items()] for x in df.to_dict(orient='records')]
This would probably work, not sure it is straightforward though.

How to group field as array in sequlize?

I have a sql table products:
+-----------+------+--------+
| productid | rate | name |
+-----------+------+--------+
| 100 | 80 | orange |
| 100 | 10 | orange |
| 102 | 100 | banana |
+-----------+------+--------+
I want to group by productid all the rates to array..
How to get using sequelize the following object (via find method)?
{
products: [{
productid: 100,
name: 'orange',
rate: [ 80, 10 ]
},
{
productid: 102,
name: 'banana'
rate: [100]
}
]
}
Suppose your table name is demo table
SELECT *
FROM demo frst, demo snd
WHERE frst.productid = snd.productid
Group By frst.productid;
this will give the expected result in the sql, if you use sequelize than it will give the same result i think so or some what you will have to modified after response

How to modify the following cypher syntax in AgensGraph?

MATCH (wu:wiki_user)
OPTIONAL MATCH (n:wiki_doc{author:wu.uid}), (o:wiki_doc{editor:wu.uid})
RETURN wu.uid AS User_id, wu.org AS Organization, wu.email AS email, wu.token AS balance,
count(n) AS Writing, count(o) AS Modifying;
user_id | organization | email | balance | writing | modifying
--------------------------------------------------------------------------
"ailee" | "Org2" | "hazel#gbc.com" | 5 | 0 | 0
"hazel" | "Org1" | "hazel#gbc.com" | 5 | 2 | 2
match (n:wiki_doc{editor:'hazel'}) return n;
n
wiki_doc[9.11]
{"bid": "hazel_doc1", "cid": "Basic", "org": "Org1", "title": "Hello world!",
"author": "hazel", "editor": "hazel", "revnum": 1, "created": "2018-09-25
09:00:000", "hasfile": 2, "contents": "I was wrong", "modified": "2018-09-25
10:00:000"}
(1 row)
In fact, the number of updates in the case of hazel is 1, and 2
queries are used when the above query is used.
How to modify the query so that only one can be normally viewed.
MATCH( wu:wiki_user )
OPTIONAL MATCH (n:wiki_doc{author:wu.uid}), (o:wiki_doc{editor:wu.uid})
RETURN wu.uid AS User_id, wu.org AS Organization, wu.email AS email, wu.token AS balance,
count(distinct id(n)) as Writing, count(distinct id(o)) as Modifying;
user_id | organization | email | balance | writing | modifying
+----------------------------------------------------------+
"ailee" | "Org2" | "hazel#gbc.com" | 5 | 0 | 0
"hazel" | "Org1" | "hazel#gbc.com" | 5 | 2 | 1
(2 rows)

Postgresql join on array and transform to json

I would like to make a join on array containing ids and transform the result of this subselect into json (json array).
I have the following model:

The lnam_refs column contains identifiers that are related to the lnam column
I would like transform the column lnam_refs into something like [row_to_json(), row_to_json()] or [] or [row_to_json()] or …
I tried several methods but I can not achieve a clean result…
To try to be clearer :
Table in input:
id | label | lnam | lnam_refs
--------+----------------------+----------+-----------------------
1 | 'master1' | 11111111 | {33333333}
2 | 'master2' | 22222222 | {44444444,55555555}
3 | 'slave1' | 33333333 | {}
4 | 'slave2' | 44444444 | {}
5 | 'slave3' | 55555555 | {}
6 | 'master3' | 66666666 | {}
Results Expected:
id | label | lnam | lnam_refs | slaves
--------+----------------------+----------+-----------------------+---------------------------------
1 | 'master1' | 11111111 | {33333333} | [ {id: 3, label: 'slave1', lnam: 33333333, lnam_refs: []} ]
2 | 'master2' | 22222222 | {44444444,55555555} | [ {id: 4, label: 'slave2', lnam: 44444444, lnam_refs: []}, {id: 5, label: 'slave3', lnam: 55555555, lnam_refs: []} ]
6 | 'master3' | 66666666 | {} | []
Thanks for your help !
Here's one way to do it. (I created a table called t with that data you supplied.)
SELECT *, (SELECT JSON_AGG(ROW_TO_JSON(t2)) FROM t t2 WHERE label LIKE 'slave%' AND lnam = ANY(t1.lnam_refs)) AS slaves
FROM t t1
WHERE label LIKE 'master%'
I use the label field in the WHERE clause as I don't know how else you're determining which records should be master etc.
Result:
1;master1;11111111;{33333333};[{"id":3,"label":"slave1","lnam":33333333,"lnam_refs":[]}]
2;master2;22222222;{44444444,55555555};[{"id":4,"label":"slave2","lnam":44444444,"lnam_refs":[]}, {"id":5,"label":"slave3","lnam":55555555,"lnam_refs":[]}]
6;master3;66666666;{};