Thread: Reporting by family tree
I have a table of members of a large family extendending back to eight generations. The current members contribute a monthly amount to the family fund. Only true descendants are included in the family list, no wives, no husbands. There are two tables
1 - Names with the following fields: idno (unique) --family member
parentid -- id number of the parent who connected the child to the family
etc
etc
2 – Contributions with fields: idno
etc
etc
Now I want to report Names and contributions par family tree: My ideal is to list grandfather, father, children based on the two fields (id, parentid).
Any suggestions?
Thanks in advance
|
I have a table of members of a large family extendending back to eight generations. The current members contribute a monthly amount to the family fund. Only true descendants are included in the family list, no wives, no husbands. There are two tables
1 - Names with the following fields: idno (unique) --family member
parentid -- id number of the parent who connected the child to the family
etc
etc
2 – Contributions with fields: idno
etc
etc
Now I want to report Names and contributions par family tree: My ideal is to list grandfather, father, children based on the two fields (id, parentid).
Any suggestions?
Thanks in advance
SELECT namba,
jina,
baba,
babu,
nasaba_1,
daraja
FROM majina2
WHERE majina2.nasaba_1 IN (SELECT DISTINCT namba FROM majina2)
UNION ALL
SELECT mtoto.namba,
mtoto.jina,
mtoto.baba,
mtoto.babu,
mtoto.nasaba_1,
daraja
FROM majina2 mtoto
WHERE mtoto.nasaba_1 NOT IN (SELECT DISTINCT namba FROM majina2)
)
SELECT g.jina AS jina_la_mtoto,
g.baba AS baba_wa_mtoto,
g.babu AS babu_wa_mtoto,
g.namba,
mzazi.jina AS jina_la_mzazi,
mzazi.baba AS jina_la_baba_la_mzazi,
g.daraja
FROM ukoo g
JOIN majina2 mzazi
ON g.namba = mzazi.namba
ORDER BY g.namba;
jina_la_mtoto | baba_wa_mtoto | babu_wa_mtoto | namba | jina_la_mzazi | jina_la_baba_la_mzazi | daraja |
---------------+---------------+---------------+--------+---------------+-----------------------+-------- | ||||||
Ibrahim | Khamis | Haji | 100001 | Ibrahim | Khamis | 6 |
Asia | Khamis | Haji | 100002 | Asia | Khamis | 6 |
Zubeir | Khamis | Haji | 100003 | Zubeir | Khamis | 6 |
Asha | Mwinyi | Bakari | 100004 | Asha | Mwinyi | 6 |
Mariama | Mwinyi | Bakari | 100005 | Mariama | Mwinyi | 6 |
Zainab | Ibrahim | Khamis | 100006 | Zainab | Ibrahim | 7 |
Fatma | Ibrahim | Khamis | 100007 | Fatma | Ibrahim | 7 |
Shaban | Ibrahim | Khamis | 100162 | Shaban | Ibrahim | 7 |
Alicia | Shaban | Ibrahim | 100163 | Alicia | Shaban | 8 |
I suppose you ought to be using, recursive CTE queriesDocumentation can be found at: 7.8. WITH Queries (Common Table Expressions)
7.8. WITH Queries (Common Table Expressions)
7.8. WITH Queries (Common Table Expressions) # 7.8.1. SELECT in WITH 7.8.2. Recursive Queries 7.8.3. Common Tabl...
On Thursday, 5 October 2023 at 16:44:46 GMT+5:45, Ibrahim Shaame <ishaame@gmail.com> wrote:I have a table of members of a large family extendending back to eight generations. The current members contribute a monthly amount to the family fund. Only true descendants are included in the family list, no wives, no husbands. There are two tables
1 - Names with the following fields: idno (unique) --family member
parentid -- id number of the parent who connected the child to the family
etc
etc
2 – Contributions with fields: idno
etc
etc
Now I want to report Names and contributions par family tree: My ideal is to list grandfather, father, children based on the two fields (id, parentid).
Any suggestions?
Thanks in advance
WITH RECURSIVE ukoo AS (
SELECT namba,
jina,
baba,
babu,
nasaba_1,
daraja
FROM majina2
WHERE majina2.nasaba_1 IN (SELECT DISTINCT namba FROM majina2)
UNION ALL
SELECT mtoto.namba,
mtoto.jina,
mtoto.baba,
mtoto.babu,
mtoto.nasaba_1,
daraja
FROM majina2 mtoto
WHERE mtoto.nasaba_1 NOT IN (SELECT DISTINCT namba FROM majina2)
SELECT g.jina AS jina_la_mtoto,
g.baba AS baba_wa_mtoto,
g.babu AS babu_wa_mtoto,
g.namba,
mzazi.jina AS jina_la_mzazi,
mzazi.baba AS jina_la_baba_la_mzazi,
g.daraja
FROM ukoo g
JOIN majina2 mzazi
ON g.namba = mzazi.namba
ORDER BY g.namba;
On Thu, Oct 5, 2023 at 7:54 AM Ibrahim Shaame <ishaame@gmail.com> wrote:WITH RECURSIVE ukoo AS (
SELECT namba,
jina,
baba,
babu,
nasaba_1,
daraja
FROM majina2
WHERE majina2.nasaba_1 IN (SELECT DISTINCT namba FROM majina2)
UNION ALL
SELECT mtoto.namba,
mtoto.jina,
mtoto.baba,
mtoto.babu,
mtoto.nasaba_1,
daraja
FROM majina2 mtoto
WHERE mtoto.nasaba_1 NOT IN (SELECT DISTINCT namba FROM majina2)The reason it is called a "recursive" CTE is that the subquery following the union all is recursive in nature - i.e., it should refer to itself. You named the CTE ukoo but you never actually refer to ukoo in the recursive subquery. Thus, you have not written a recursive query.When you reference the recursive "table" in the subquery its contents contain the results of the previous iteration, that is what allows you to select a child record and then consider that record a parent when finding the next depth/layer of children.David J.
Thanks David for the reply. But I think you missed part of the code, which refers to ukoo:)
SELECT g.jina AS jina_la_mtoto,
g.baba AS baba_wa_mtoto,
g.babu AS babu_wa_mtoto,
g.namba,
mzazi.jina AS jina_la_mzazi,
mzazi.baba AS jina_la_baba_la_mzazi,
g.daraja
FROM ukoo g
JOIN majina2 mzazi
ON g.namba = mzazi.namba
ORDER BY g.namba;Any suggestion?
Example Below:-- create a test family tablecreate table family as(select1 as id,null::integer as parent_id,'Grandfather1' as nameunion allselect2 as id,null::integer as parent_id,'Grandfather2' as nameunion allselect3 as id,1 as parent_id,'Father1-1' as nameunion allselect4 as id,1 as parent_id,'Father1-2' as nameunion allselect5 as id,2 as parent_id,'Father2-1' as nameunion allselect6 as id,3 as parent_id,'Son1-1-1' as nameunion allselect7 as id,4 as parent_id,'Son1-2-1' as nameunion allselect8 as id,5 as parent_id,'Son2-1-1' as name);-- create a test contribution tablecreate table contribution as(select1 as contributor_id,'2020-01-01' as date,300.00 as contribution_amountunion allselect1 as contributor_id,'2020-02-01' as date,255.00 as contribution_amountunion allselect1 as contributor_id,'2020-03-01' as date,45.65 as contribution_amountunion allselect2 as contributor_id,'2020-05-01' as date,22.55 as contribution_amountunion allselect2 as contributor_id,'2020-01-01' as date,450.00 as contribution_amountunion allselect3 as contributor_id,'2020-02-01' as date,200.00 as contribution_amountunion allselect4 as contributor_id,'2020-03-01' as date,150.00 as contribution_amountunion allselect4 as contributor_id,'2020-04-01' as date,60.45 as contribution_amountunion allselect4 as contributor_id,'2020-05-01' as date,300.00 as contribution_amountunion allselect5 as contributor_id,'2020-06-01' as date,1250.00 as contribution_amountunion allselect6 as contributor_id,'2020-01-01' as date,66.50 as contribution_amountunion allselect7 as contributor_id,'2020-02-01' as date,855.00 as contribution_amountunion allselect8 as contributor_id,'2020-02-01' as date,25.00 as contribution_amount);-- execute recursive query, all children inheriting contribution sum of parentswith recursive cte as(selectf.id,f.parent_id,c.contribution_amountfromfamily fjoin contribution c onf.id = c.contributor_idunion allselectf.id,f.parent_id,cte.contribution_amountfromctejoin family f oncte.id = f.parent_id)selectid,name,sum(contribution_amount) as total_contributionfromctegroup byid,nameorder byid;-- execute recursive query, parents have sum of all contributions of its childrenwith recursive cte as(selectf.id,f.parent_id,c.contribution_amountfromfamily fjoin contribution c onf.id = c.contributor_idunion allselectf.id,f.parent_id,cte.contribution_amountfromctejoin family f oncte.parent_id = f.id)selectid,name,sum(contribution_amount) as total_contributionfromctegroup byid,nameorder byid;Change your SQL accordingly. Also, you can add month field to yield results per month.
id | name | total_contribution
----+--------------+--------------------
1 | Grandfather1 | 600.65
2 | Grandfather2 | 472.55
3 | Father1-1 | 800.65
4 | Father1-2 | 1111.10
5 | Father2-1 | 1722.55
6 | Son1-1-1 | 867.15
7 | Son1-2-1 | 1966.10
8 | Son2-1-1 | 1747.55
But what I want to get is grandfather - father - children:
1 - Grandfather1
3 - father1-1
6 - son1-1
7 – son1-2
4 - Father1-2
8 - son2-1
2 – Grandfather2
5 - Father2-1
etc
Any suggestion
Thank you David and Swastik, Swastik, I will work on it and will let you know.Thanks again for your helpOn Mon, Oct 16, 2023 at 4:31 PM swastik Gurung <gurung_swastik@yahoo.com> wrote:Example Below:-- create a test family tablecreate table family as(select1 as id,null::integer as parent_id,'Grandfather1' as nameunion allselect2 as id,null::integer as parent_id,'Grandfather2' as nameunion allselect3 as id,1 as parent_id,'Father1-1' as nameunion allselect4 as id,1 as parent_id,'Father1-2' as nameunion allselect5 as id,2 as parent_id,'Father2-1' as nameunion allselect6 as id,3 as parent_id,'Son1-1-1' as nameunion allselect7 as id,4 as parent_id,'Son1-2-1' as nameunion allselect8 as id,5 as parent_id,'Son2-1-1' as name);-- create a test contribution tablecreate table contribution as(select1 as contributor_id,'2020-01-01' as date,300.00 as contribution_amountunion allselect1 as contributor_id,'2020-02-01' as date,255.00 as contribution_amountunion allselect1 as contributor_id,'2020-03-01' as date,45.65 as contribution_amountunion allselect2 as contributor_id,'2020-05-01' as date,22.55 as contribution_amountunion allselect2 as contributor_id,'2020-01-01' as date,450.00 as contribution_amountunion allselect3 as contributor_id,'2020-02-01' as date,200.00 as contribution_amountunion allselect4 as contributor_id,'2020-03-01' as date,150.00 as contribution_amountunion allselect4 as contributor_id,'2020-04-01' as date,60.45 as contribution_amountunion allselect4 as contributor_id,'2020-05-01' as date,300.00 as contribution_amountunion allselect5 as contributor_id,'2020-06-01' as date,1250.00 as contribution_amountunion allselect6 as contributor_id,'2020-01-01' as date,66.50 as contribution_amountunion allselect7 as contributor_id,'2020-02-01' as date,855.00 as contribution_amountunion allselect8 as contributor_id,'2020-02-01' as date,25.00 as contribution_amount);-- execute recursive query, all children inheriting contribution sum of parentswith recursive cte as(selectf.id,f.parent_id,c.contribution_amountfromfamily fjoin contribution c onf.id = c.contributor_idunion allselectf.id,f.parent_id,cte.contribution_amountfromctejoin family f oncte.id = f.parent_id)selectid,name,sum(contribution_amount) as total_contributionfromctegroup byid,nameorder byid;-- execute recursive query, parents have sum of all contributions of its childrenwith recursive cte as(selectf.id,f.parent_id,c.contribution_amountfromfamily fjoin contribution c onf.id = c.contributor_idunion allselectf.id,f.parent_id,cte.contribution_amountfromctejoin family f oncte.parent_id = f.id)selectid,name,sum(contribution_amount) as total_contributionfromctegroup byid,nameorder byid;Change your SQL accordingly. Also, you can add month field to yield results per month.
But what I want to get is grandfather - father - children:1 - Grandfather1
3 - father1-1
6 - son1-1
7 – son1-2
4 - Father1-2
8 - son2-1
2 – Grandfather2
5 - Father2-1
etc
Any suggestion
On Wed, Oct 25, 2023 at 9:55 AM David G. Johnston <david.g.johnston@gmail.com> wrote: > > On Wed, Oct 25, 2023 at 5:21 AM Ibrahim Shaame <ishaame@gmail.com> wrote: >> >> But what I want to get is grandfather - father - children: >> >> 1 - Grandfather1 >> >> 3 - father1-1 >> >> 6 - son1-1 >> >> 7 – son1-2 >> >> 4 - Father1-2 >> >> 8 - son2-1 >> >> 2 – Grandfather2 >> >> 5 - Father2-1 >> >> etc >> >> >> Any suggestion >> > > If you want a different ordering of the output change the ORDER BY specification. > > Specifically, you want to order by the path of each person. Since that can only be determined during the traversal youneed to create the path data yourself. I suggest using an integer[] (integer array) to store the path using ID valuesas breadcrumbs. > > (Not the OP just someone following the list trying to learn.) 'using ID values as breadcrumbs' - - - can I interpret that to mean the ordinal numbers 1-8 listed (more implied)? TIA
On Wed, Oct 25, 2023 at 9:55 AM David G. Johnston
<david.g.johnston@gmail.com> wrote:
>
> On Wed, Oct 25, 2023 at 5:21 AM Ibrahim Shaame <ishaame@gmail.com> wrote:
>>
>> But what I want to get is grandfather - father - children:
>>
>> 1 - Grandfather1
>>
>> 3 - father1-1
>>
>> 6 - son1-1
>>
>> 7 – son1-2
>>
>> 4 - Father1-2
>>
>> 8 - son2-1
>>
>> 2 – Grandfather2
>>
>> 5 - Father2-1
>>
>> etc
>>
>>
>> Any suggestion
>>
>
> If you want a different ordering of the output change the ORDER BY specification.
>
> Specifically, you want to order by the path of each person. Since that can only be determined during the traversal you need to create the path data yourself. I suggest using an integer[] (integer array) to store the path using ID values as breadcrumbs.
>
>
(Not the OP just someone following the list trying to learn.)
'using ID values as breadcrumbs' - - - can I interpret that to mean
the ordinal numbers 1-8 listed (more implied)?
On Wed, Oct 25, 2023 at 5:17 PM David G. Johnston <david.g.johnston@gmail.com> wrote: > > On Wed, Oct 25, 2023 at 9:13 AM o1bigtenor <o1bigtenor@gmail.com> wrote: >> >> On Wed, Oct 25, 2023 at 9:55 AM David G. Johnston >> <david.g.johnston@gmail.com> wrote: >> > >> > On Wed, Oct 25, 2023 at 5:21 AM Ibrahim Shaame <ishaame@gmail.com> wrote: >> >> >> >> But what I want to get is grandfather - father - children: >> >> >> >> 1 - Grandfather1 >> >> >> >> 3 - father1-1 >> >> >> >> 6 - son1-1 >> >> >> >> 7 – son1-2 >> >> >> >> 4 - Father1-2 >> >> >> >> 8 - son2-1 >> >> >> >> 2 – Grandfather2 >> >> >> >> 5 - Father2-1 >> >> >> >> etc >> >> >> >> >> >> Any suggestion >> >> >> > >> > If you want a different ordering of the output change the ORDER BY specification. >> > >> > Specifically, you want to order by the path of each person. Since that can only be determined during the traversalyou need to create the path data yourself. I suggest using an integer[] (integer array) to store the path usingID values as breadcrumbs. >> > >> > >> (Not the OP just someone following the list trying to learn.) >> >> 'using ID values as breadcrumbs' - - - can I interpret that to mean >> the ordinal numbers 1-8 listed (more implied)? >> > > Yes, the numbers 1-8 are the values assigned to these 8 example individuals as their unique identifiers. > > {1} > {1,3} > {1,3,6} > {1,3,7} > {1,4} > {1,4,8} > {2} > {2,5} > Thank you Mr David.