2

Using PostgreSQL 9.4.1, I am trying to identify/display the occurrences of values over 3 different columns. See below (apologies for the formatting, I can't get a proper table format. Type, type1 and type2 are the column names. The table name is documents

CREATE TABLE documents
AS
  SELECT *
  FROM ( VALUES 
    ('USA','China','Africa'),
    ('China','USA','Chemicals'), 
    ('Chemicals','Africa','USA')
  ) AS t(type,type1,type2);

Below is \d+ of the table:

     Column     |  Type  |                       Modifiers                        
----------------+--------+--------------------------------------------------------
 id             | bigint | not null default nextval('documents_id_seq'::regclass)
 title          | text   | 
 description    | text   | 
 source         | text   | 
 url            | text   | 
 emaillink      | text   | 
 emailurl       | text   | 
 type           | text   | 
 language       | text   | 
 author         | text   | 
 publisheddate  | date   | default ('now'::text)::date
 comments       | text   | 
 classification | text   | 
 submittedby    | text   | 
 localurl       | text   | 
 type1          | text   | 
 type2          | text   | 
Indexes:
    "documents_pkey" PRIMARY KEY, btree (id)

I would like a query that returns:

Africa - 2   
Chemicals - 2  
China - 2   
USA - 3   

This is a query likely to get run fairly liberally, so I'd like to avoid expensive queries if at all possible.

3 Answers 3

1

You can use union all to pivot the columns into rows and then do a group by to count the occurrences for each type

select type, count(*) from (
    select type1 as type from mytable
    union all select type2 from mytable
    union all select type3 from mytable
) t1 group by type
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks so much! I only have about 1000 records, so I couldn't easily discern a difference in speed, but went with the full join anyways.
How would I sort the full join?
FYI, the full join doesn't actually merge the three columns for some reason. The output appears to output each column individually. I saw duplicates.
1

Try this:

SELECT WORD, COUNT(1) OCCURENCES
FROM (
    SELECT Type FROM TableName
    UNION ALL
    SELECT Type1 FROM TableName
    UNION ALL
    SELECT Type2 FROM TableName)
GROUP BY WORD;

1 Comment

If I could select both as answers, I would, you were only what...2 minutes behind FuzzyTree?
0

Alternatively you can use ARRAY[]/unnest()

SELECT x, count(x)
FROM (
  SELECT ARRAY[type,type1,type2] AS array
  FROM documents
) AS t
CROSS JOIN LATERAL unnest(t.array)
  AS x
GROUP BY x;

     x     | count 
-----------+-------
 USA       |     3
 China     |     2
 Chemicals |     2
 Africa    |     2
(4 rows)

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.