如何获得独特的用户约定?

时间:2013-03-03 14:35:18

标签: sql postgresql subquery

我正在尝试使用user engagements

列出唯一的engagement_type

我以前有过以下查询。

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);

返回:

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

哪个好。现在,我想要包含engagment类型。我想出了这个:

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);

现在返回:

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

上面唯一的问题。结果不再独特。如您所见,Joe和Megan有两个条目。

知道如何才能让它发挥作用吗?

2 个答案:

答案 0 :(得分:1)

在PostgreSQL中使用DISTINCT ON更简单。
由于缺乏定义,我根据其排序顺序选择第一个engagement_type

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);

详情,链接和说明:

如果您想要所有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 :(得分:0)

如果只需要一行,则需要从GROUP BY子句中删除engagement_type。但是,这不会显示所有不同的engagement_type。

如果要在一行中列出engagement_types而不复制用户详细信息,请使用ARRAY_TO_STRING函数。这会将结果污染到一行。因此,您可以将评论表中的参与类型列为逗号分隔列表。