N1QL Concatenate many children rows into single string - couchbase

Consider in Couchbase I have a person database, with 3 documents:
Person A
Child AA
Grand AAA
Grand AAB
Child AB
Grand ABA
Grand ABB
Person B
Person C
Child CA
Child CB
Grand CBA
Is there an easy way to turn this into following results using N1QL?
I am trying to display each person with their grand children displayed into strings?
Person A, Grand: "AAA, AAB, ABA, ABB"
Person B, Grand: ""
Person C, Grand: "CBA"

You can do the following:
SELECT p.name AS p, ENCODE_JSON(ARRAY_AGG(g.name)) AS g
FROM person AS p LEFT OUTER UNNEST p.child AS c LEFT OUTER UNNEST c.grand AS g
GROUP BY p;

Related

mysql join a table to itself from a bridging table

I have two tables that references each other via id. I want to connect a given name in the first table, to a relation with one or many persons using a second table. See example
Person
id
name
Adress
1
Jonas
Sturmwind Street 12 5431
2
Thomas
New Banksy Home 14 5432
3
Therese
Redcarpet Willow 1 6623
4
Nicko
Redcarpet Willow 1 6623
5
Sandra
Mcmurdo Station
Related
related_from_id
related_to_id
Relation
1
2
"Sibling"
1
5
"Sibling"
3
4
"Parent"
Given a name, how can I make a mysql query that gives me any potential siblings name and adress.
For instance I query with param "Jonas" and expect the result set to be
Relation
Name
Related to
Adress
Jonas
"Thomas"
"New Banksy Home 14 5432"
"Sandra"
"Mcmurdo Station"
In order to have your result
SELECT
p.name AS NAME,
p1.name AS relatedTo,
p1.Address
FROM
Person p,
Related r,
Person p1
WHERE r.related_from_id = p.id
AND r.related_to_id = p1.id
AND p.name = 'Jonas' ;
However, if the relationship is in any direction, #The Impater's answer has you covered.
I would assume you want to walk the related table in any direction (left-right or right-left).
You can do:
select p.name, o.name as related_to, o.address
from person p
join related r on p.id in (r.related_from_id, r.related_to_id)
join person o on r.related_from_id = p.id and o.id = related_to_id
or r.related_to_id = p.id and o.id = related_from_id
where p.name = 'Jonas'

Filtering Max Number of Votes each party got for each year in SQL

I have 3 tables each containing election_id election_year election_type (which is a string), party_name(also a string) party_ID, and the last one has Results_ID(equal to election_id) Results_party(equal to party_ID) and lastly ballots, my query has to return max number of ballots each party has ever gotten for the years in consideration for example(also desired output):
Name
Year
Ballots
Party A
2000
105
Party B
2000
95
Party C
2004
50
Party C
2008
50
I tried this
SELECT Party.party_name,Elections.election_year,Results.Results_ballots
FROM ((Elections
INNER JOIN Results
on Elections.election_ID=Results.Results_Elections
AND Elections.election_Type='Regional')
INNER JOIN Party on Party.party_ID=Results.Results_Party)
but this gives me all the parties and all the elections with all the ballots, I want max ballot count for each one
any ideas are appreciated, I'm very new to MySQL
EDIT: also tried this, which missed the last row of the table
FROM Party as p, Elections as e, Results as r
where p.party_ID=r.Results_Party and e.election_Type='Regional' AND r.Results_Elections=e.Elections_ID
group by p.party_name
So it looked like this
Name
Year
Ballots
Party A
2000
105
Party B
2000
95
Party C
2004
50
If I understood you correctly, you have to do a subquery to get the max for each party.
this is what I came up with
SELECT * FROM Party c
LEFT JOIN Results b
ON b.Results_party=c.party_ID
AND b.ballots=(SELECT MAX(d.ballots) FROM Results d WHERE d.Results_Party=c.party_ID)
LEFT JOIN Elections a
ON a.Elections_ID=b.Results_ID

mysql self-join fixing result order when parent is doesnot exists

I i have a table named Taxonomy it preaty much holds everything that has to do with the structure of the organization. as a school example table looks like
id | name | type | parent
1 | 2014 | year | null
2 | igcse| dep | 1
3 | kg1 | grade| 2
4 | c1 | class| 3
4 types, upper most is the school year (2014-2015) for example. under it school department, under it grade (grade1,2,3 etc) under it multiple classes.
when i need to get this i run a self join query like this :
SELECT y.name AS year,
d.name AS dep,
g.name AS grade,
c.name AS class,
e.name AS exam
FROM `taxonomys` e
left JOIN `taxonomys` c on c.id = e.parent
left JOIN `taxonomys` g on g.id = c.parent
left JOIN `taxonomys` d on d.id = g.parent
left JOIN `taxonomys` y on y.id = d.parent
where c.type in ('grade','department','class','year')
its working fine except with the so many nulls i get !
example result of query
as you can see, the classes shows correctly with year under year field,
yet on first row, year is under Class field, (shifted 3 cells).
when ever there is a null value is shifted. how can i fix that ?
thanks alot
EDIT
What is this table ?
A variation of Adjacency List Model, I added an extra column named type so that I can identify level of any row without having to retrieve whole path.
Table hold the structure of the school. example
In every new year, they create A Year example "2014-2015", then inside this year creates the school different departments "american diploma, Highschool, playshool, etc.." under that comes the school grades and under every grade come the classes..
Example
id name type parent
1 2014-2015 year null
2 highschool dep. 1
3 grade 10 grade 2
4 grade 11 grade 2
5 class a class 3
6 class b class 3
These inputs means
2014-2015
|__Highschool
|__ grade 10
|__ class a
|__ class b
|__ grade 11
after than another table link students to Class node, and another table link posts to class's and so on.
so this table basically holds the school structures. since years, departments, and grades are only there for organization of the school users "there is no data except names needed for them" i decided to have the all in one table.
Why did you build it in this a very very very bad/anti-pattern design ?
its actually working very nice for me !
(we hv 4 years with all the departments and students and classes, over 100k posts linked to user/class and over 10k users and its working smooth so far !)
I don't know what your output is supposed to be, and I don't know how your query is suppposed to get it, and I don't know how you are encoding what information in your table, but I suspect that the query below gives the result you want, and that it's somewhat redundant (namely the last 4 lines), and that your design is really, really, really an anti-pattern.
/*
rows y.n,d.n,g.n,c.n,e.n
where
taxonomies(y.i,y.n,'year',y.p)
AND taxonomies(d.i,d.n,'dep',y.i) AND taxonomies(g.i,g.n,'grade',d.p)
AND taxonomies(c.i,c.n,'class',g.i) AND taxonomies(e.i,e.n,'exam',c.i)
*/
SELECT y.name AS year,
d.name AS dep,
g.name AS grade,
c.name AS class,
e.name AS exam
FROM `taxonomys` y
JOIN `taxonomys` d on y.id = d.parent
JOIN `taxonomys` g on d.id = g.parent
JOIN `taxonomys` c on g.id = c.parent
JOIN `taxonomys` e on c.id = e.parent
WHERE y.type = 'year'
AND d.type = 'dep'
AND g.type = 'grade'
AND c.type = 'class'
AND e.type = 'exam'
They are shifting to the left and you are doing a left JOIN. That's a clue. I suggest to change it to only join. When you perform a left JOIN you get all the rows from the left table in conjunction with the matching rows from the right table. If there are no columns matching in the right table, it returns NULL values.
The columns shifting places is new to my eyes (not a SQL expert here though) but it seems to me that it could be related with the fact that you are retrieving all the data from the same table taxonomys.

Complex query in MySQL with multiple joins

Have been trying (unsuccessfully) to write a query with multiple joins, which is why I am now asking for your help.
Table structure:
A parent which has many children and many cars
A child which has one parent and many cars
A car which either has one parent or one child.
(source: zxq.net)
What I am trying to do:
I am trying to find to find the total value of the cars per parent. (A parent "owns" his childrens cars, so the sum of the value of the childrens cars should be added to the sum of the value of the parents cars).
For example, I want my query to return:
If Thomas has a car worth 5000, and one child who has two cars also worth 5000, the total value for thomas is 5000 + 5000 * 2 = 15000.
If John has two cars worth 2000, and two children who each have two cars worth 2000, the total value for John is : 2000 * 2 + 2000 * 2 + 2000 * 2 = 12000.
In short:
name | total
--------------
Thomas | 15000
John | 12000
So far I have:
SELECT p.name,
SUM(IFNULL(carparent.price, 0)+IFNULL(carchild.price, 0)) total
FROM parent p
# first get the childrens cars
INNER JOIN child c ON c.parent_id = p.id
INNER JOIN car carchild ON carchild.child_id = c.id
# now get the parents cars
LEFT JOIN car carparent ON carparent.parent_id = p.id
GROUP BY p.name
ORDER BY total DESC
Which is returning strange results when a parent has more than one child... I think I am getting confused with all the JOINS..
Anyways, if anyone could point me in the correct direction, I would be very grateful :)
Many thanks,
I tried to make your database as stated earlier.
Here is my solution.
select
Name,
(select sum(price)
from car
where car.Parent_id=parent.id) as `Value Parent Car(s)`,
(select sum(price)
from car
left join child
on car.child_id=child.id
where child.parent_id=parent.id) as `Value of Child car(s)`
from parent
Or to obtain a total
select
id,
Name,
((select sum(price)
from car
where car.Parent_id=parent.id) +
(select sum(price)
from car
left join child
on car.child_id=child.id
where child.parent_id=parent.id)) as `Total Value car(s)`
from parent
I am sure though that a better structure can be found... By example, a car is own by a person and a person can be a parent, a child or both...

Retrieve data from two tables with indirect relation(from another table)

I have 3 tables
Division
id name
1 A
2 B
Region
Id name Divsion_id
01 Rim A
Territory
Id name region_id
001 a 01
002 b 01
003 c 01
Now I want to write a query such way that user will select division and its respective territories should get displayed.
How can I write this query, as
there is no direct relation between Divsion and Region?
select t.* from territory t
inner join region r on r.id = t.region_id
inner join devision d on d.name = r.division_id
where d.name = 'A'
Another approach would be to use IN operator with sub query. Inner query projects all regions having given region id and outer query looks for territories with selected regions. Though joins should perform better than nested query.
select * from territory where region_id in (select region_id from region where devision_id=<division id>)