26

I have such a table

id SERIAL,
user_id INT,
community_id INT[],

The table filled this way:

id | user_id | community_id 
1  |  1      |   {2, 4}
2  |  5      |   {2, 5} 
3  |  10     |   {2, 4}

I'd like to get COUNT of users which each community has, community_id is array cuz user can be in several community at the same time.

The query should be simple as:

SELECT community_id, COUNT(user_id) FROM tbl GROUP BY community_id

The result should be like this:

community_id  | user_count
2             |  3
4             |  2
5             |  1

I do not know how to GROUP BY array column. Can anybody help me ?

6
  • 5
    This query would be as simply as you expect, if the model was properly normalized. Commented Nov 2, 2015 at 9:56
  • can you be more specific ? Commented Nov 2, 2015 at 9:59
  • You have a classical one-to-many relationship. That shouldn't be represented with an array but with two tables. en.wikipedia.org/wiki/Database_normalization#Example Commented Nov 2, 2015 at 10:00
  • 7
    Please do not advise me to use junction table to implement MANY to MANY relation. I am not developing the structure of database right now, I am trying to pull needed data from tables which already exist Commented Nov 2, 2015 at 10:00
  • 2
    I completely agree, but I have what I have. Commented Nov 2, 2015 at 10:12

2 Answers 2

33

You can use unnest() to get a normalized view on the data, and the aggregate:

select community_id, count(*)
from (
  select unnest(community_id) as community_id
  from tbl 
) t
group by community_id
order by community_id;

But you should really fix your data model.

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

Comments

2
SELECT unnest(community_id) community_id ,
       count(user_id) user_count
FROM TABLE_NAME
GROUP BY 1 --community_id = 1 and user_count = 2 (index of a column in select query)
ORDER BY 1

unnest(anyarray): Expand an array to a set of rows

i.e select unnest(ARRAY[1,2]) will give

   unnest
   ------
       1
       2

Comments

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.