0

私はユニークなものをリストしようとして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

それは結構です。ここで、エンゲージメント タイプを含めたいと思います。私はこれを思いついた:

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 つのエントリがあります。

どうすればこれを機能させることができますか?

4

2 に答える 2

1

DISTINCT ONPostgreSQL でよりシンプルに。
定義がない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

于 2013-03-03T18:28:37.003 に答える
0

行が 1 つだけ必要な場合は、GROUP BY 句からengagement_type を削除する必要があります。ただし、これではすべての異なる Engagement_type が表示されるわけではありません。

ユーザーの詳細を複製せずに、engagement_types を 1 行にリストする場合は、ARRAY_TO_STRING 関数を使用します。これにより、結果が 1 行に汚染されます。そのため、コメント テーブルのエンゲージメント タイプをカンマ区切りのリストとしてリストできます。

于 2013-03-03T16:08:25.123 に答える