1

The answer to my question was almost here: PostgreSQL array_agg order

Except that I wanted to array_agg over a window function:

 select distinct c.concept_name, 
        array_agg(c2.vocabulary_id||':'||c2.concept_name 
                  order by c2.vocabulary_id, c2.concept_name) 
            over (partition by ca.min_levels_of_separation), 
        ca.min_levels_of_separation
 from concept c
 join concept_ancestor ca on c.concept_id = ca.descendant_concept_id 
      and max_levels_of_separation > 0
 join concept c2 on ca.ancestor_concept_id = c2.concept_id 
 where 
 c.concept_code = '44054006'
 order by min_levels_of_separation;

So, maybe this will work in some future version, but I get this error

 ERROR:  aggregate ORDER BY is not implemented for window functions
 LINE 2: select distinct c.concept_name, array_agg(c2.vocabulary_id||...
                                    ^

I should probably be selecting from a subquery like the first answer to the quoted question above suggests. I was hoping for something as simple as the order by (in that question's second answer). Or maybe I'm just being lazy about the query and should be doing a group by instead of select distinct.

I did try putting the order by in the windowing function (over (partition by ca.min_levels_of_separation order by c2.vocabulary_id, c2.concept_name)), but I get these sort of repeated rows that way:

 "Type 2 diabetes mellitus";"{"MedDRA:Diabetes mellitus"}";1
 "Type 2 diabetes mellitus";"{"MedDRA:Diabetes mellitus","MedDRA:Diabetes mellitus (incl subtypes)"}";1
 "Type 2 diabetes mellitus";"{"MedDRA:Diabetes mellitus","MedDRA:Diabetes mellitus (incl subtypes)","SNOMED:Diabetes mellitus"}";1

(btw: http://www.ohdsi.org/ if you happen to be curious about where I got the medical vocabulary tables)

2 Answers 2

2

Yes, it does look like I was being muddle-headed and didn't need the window function. This seems to work:

 select  c.concept_name, 
         array_agg(c2.vocabulary_id||':'||c2.concept_name 
                   order by c2.vocabulary_id, c2.concept_name), 
         ca.min_levels_of_separation
 from concept c
 join concept_ancestor ca on c.concept_id = ca.descendant_concept_id 
      and max_levels_of_separation > 0
 join concept c2 on ca.ancestor_concept_id = c2.concept_id
 where c.concept_code = '44054006'
 group by c.concept_name, ca.min_levels_of_separation
 order by min_levels_of_separation

I won't accept my answer for a while since it just avoids the question instead of actually answering it, and someone might have something more useful to say on the matter.

Sign up to request clarification or add additional context in comments.

1 Comment

Looks totally fine at a quick glance
0

like this :

select distinct c.concept_name, 
    array_agg(c2.vocabulary_id||':'||c2.concept_name ) over (partition by ca.min_levels_of_separation  order by c2.vocabulary_id, c2.concept_name), 
    ca.min_levels_of_separation
from concept c
join concept_ancestor ca on c.concept_id = ca.descendant_concept_id 
  and max_levels_of_separation > 0
join concept c2 on ca.ancestor_concept_id = c2.concept_id 
where 
c.concept_code = '44054006'
order by min_levels_of_separation;

1 Comment

Sorry, I should have said I tried that. It gives me sort of repeated rows. I'll edit the question to show what I mean (can't format it in a comment.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.