How to get unique user tasks?

I am trying to list unique user engagementswithengagement_type

I had the following request.

SELECT u.id, u.fname, u.lname FROM (
  SELECT id, engagement_type FROM (
    SELECT user_id AS id, 'comment'
    FROM comments WHERE commentable_id = 48136 AND commentable_type = 'Video'
    UNION ALL
    SELECT user_id AS id, 'like'
    FROM likes WHERE likeable_id = 48136 AND likeable_type = 'Video'
  ) AS a
  GROUP BY id
  LIMIT 10
) b JOIN users u USING (id);

Return:

id        | fname      | lname
------------------------------
1         | joe        | abc
2         | sarah      | qer
3         | megan      | tryey
4         | john       | vdfa

This is normal. Now I want to enable the engagment type. I came up with this:

SELECT u.id, u.fname, u.lname, engagement_type FROM (
  SELECT id, engagement_type FROM (
    SELECT user_id AS id, 'comment' AS engagement_type
    FROM comments WHERE commentable_id = 48136 AND commentable_type = 'Video'
    UNION ALL
    SELECT user_id AS id, 'like' AS engagement_type FROM likes
    WHERE likeable_id = 48136 AND likeable_type = 'Video'
  ) AS a
  GROUP BY id, engagement_type
  LIMIT 10
) b JOIN users u USING (id);

What now returns:

id        | fname      | lname    | engagement_type
---------------------------------------------------
1         | joe        | abc      | comment
2         | sarah      | qer      | like
3         | megan      | tryey    | like
4         | john       | vdfa     | like
1         | joe        | abc      | like     
3         | megan      | tryey    | comment

The only problem with the above. The results are no longer unique. As you can see, Joe and Megan have 2 entries.

Any idea how I can make this work?

0
source share
2 answers

Simplify with DISTINCT ONin PostgreSQL.
Due to the lack of definition, I select the first engagement_typeaccording to its sort order:

SELECT u.id, u.fname, u.lname, b.engagement_type
FROM  (
   SELECT DISTINCT ON (1)
          id, engagement_type
   FROM (
      SELECT user_id AS id, 'comment' AS engagement_type
      FROM   comments
      WHERE  commentable_id = 48136
      AND    commentable_type = 'Video'

      UNION ALL
      SELECT user_id, 'like'
      FROM   likes
      WHERE  likeable_id = 48136 
      AND    likeable_type = 'Video'
      ) a
   ORDER  BY 1, 2
   LIMIT  10
   ) b
JOIN users u USING (id);

Details, links and explanations:

engagement_types:

  SELECT id, string_agg(DISTINCT engagement_type, ', ') AS engagement_types
   FROM (
      ...
      ) a
   GROUP  BY 1
   ORDER  BY <whatever>
   LIMIT  10;

string_agg() Postgres 9.0 .
, , , , ORDER BY DISTINCT ON.

+1

, engagement_type GROUP BY. .

engagement_types , , ARRAY_TO_STRING. . , , .

0

All Articles