Re: Hierarchical Query Question (PHP)

From: Andy Colson <andy(at)squeakycode(dot)net>
To: David Blomstrom <david(dot)blomstrom(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Hierarchical Query Question (PHP)
Date: 2015-10-31 14:19:29
Message-ID: 5634CDF1.1050607@squeakycode.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On 10/30/2015 05:10 PM, David Blomstrom wrote:
> Just so I understand what's going on, I can create a lookup table by pasting this code...
>

I don't know anything about biology so this data might be laughable, but its based on your original question:

http://stackoverflow.com/questions/33402831/count-descendants-in-hierarchical-query

It seemed like the parent_id column was really the rank, and I couldn't tell if it should be taxon_rank or parent_rank. Thinking more about the problem, I normalized a little, renamed some, and came up with this script. It lacks indexes and proper names, etc, etc, because I wanted to tackle one problem at a time. Hopefully its a good example.

create table rank (
id integer,
descr text
);

insert into rank values(1, 'Classes');
insert into rank values(2, 'Orders');
insert into rank values(3, 'Families');
insert into rank values(4, 'Genera');
insert into rank values(5, 'Species');

create table mammals (
id integer,
taxon text,
rank integer,
parentid integer
);

insert into mammals values (0, 'Chordata', 1, null);
insert into mammals values (1, 'Mammalia', 1, 0);
insert into mammals values (2, 'Carnivora', 2, 1);
insert into mammals values (3, 'Canidae' , 3, 2);
insert into mammals values (4, 'Canis' , 4, 3);
insert into mammals values (5, 'Canis-lupus', 5, 4);
insert into mammals values (6, 'Canis-latrans', 5, 4);

-- This query shows you the basic results. It only
-- returns the id columns. further queries build on this base one.
-- (you could this of this query as Order Chordata :-) )
with recursive heir(id, rank, parentid) as (
select m.id, 0, m.parentid
from mammals m
where taxon = 'Canis'
union all
select m.id, m.rank, m.parentid
from heir
inner join mammals m on m.parentid = heir.id
)
select * from heir;

Results:
id | rank | parentid
----+------+----------
4 | 0 | 3
5 | 5 | 4
6 | 5 | 4
(3 rows)

----
-- This looks up the columns for a more meaningful result:
with recursive heir(id, rank, parentid) as (
select m.id, 0, m.parentid
from mammals m
where taxon = 'Canidae'
union all
select m.id, m.rank, m.parentid
from heir
inner join mammals m on m.parentid = heir.id
)
select m.taxon, r.descr
from heir
inner join mammals m on m.id = heir.id
inner join rank r on heir.rank=r.id

Results:
taxon | descr
---------------+---------
Canis | Genera
Canis-lupus | Species
Canis-latrans | Species

---------
-- This, finally, groups and counts, like your original question
with recursive heir(id, rank, parentid) as (
select m.id, 0, m.parentid
from mammals m
where taxon = 'Canidae'
union all
select m.id, m.rank, m.parentid
from heir
inner join mammals m on m.parentid = heir.id
)
select r.id, r.descr, count(*)
from heir
inner join mammals m on m.id = heir.id
inner join rank r on heir.rank=r.id
group by r.id, r.descr
order by r.id

Results:
id | descr | count
----+---------+-------
4 | Genera | 1
5 | Species | 2

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Guillaume Lelarge 2015-10-31 19:18:33 Re: does pg_dump get delayed if I have a loop that does continuous insertions
Previous Message Charles Clavadetscher 2015-10-31 14:12:36 Re: Selectively Importing Data