Postgres - 使用 CTE 的 id 列的唯一值,与 GROUP BY 一起加入

Postgres - Unique values for id column using CTE, Joins alongside GROUP BY

我有一个 table referrals:

id | user_id_owner | firstname | is_active | user_type | referred_at
----+---------------+-----------+-----------+-----------+-------------
  3 |             2 | c         | t         | agent     |           3
  5 |             3 | e         | f         | customer  |           5
  4 |             1 | d         | t         | agent     |           4
  2 |             1 | b         | f         | agent     |           2
  1 |             1 | a         | t         | agent     |           1

还有一个tableactivations

    id | user_id_owner | referral_id | amount_earned | activated_at | app_id
----+---------------+-------------+---------------+--------------+--------
  2 |             2 |           3 |           3.0 |            3 | a
  4 |             1 |           1 |           6.0 |            5 | b
  5 |             4 |           4 |           3.0 |            6 | c
  1 |             1 |           2 |           2.0 |            2 | b
  3 |             1 |           2 |           5.0 |            4 | b
  6 |             1 |           2 |           7.0 |            8 | a

我正在尝试从两个 table 生成另一个 table,它只有 referrals.id 和 returns 的唯一值作为计数的列之一每个应用程序为 best_selling_app_count.

这是我的查询 运行:

with agents 
    as 
    (select 
    referrals.id, 
    referral_id, 
    amount_earned, 
    referred_at, 
    activated_at, 
    activations.app_id 
    from referrals 
    left outer join activations 
    on (referrals.id = activations.referral_id) 
    where referrals.user_id_owner = 1), 
    distinct_referrals_by_id 
    as 
    (select 
    id, 
    count(referral_id) as activations_count, 
    sum(coalesce(amount_earned, 0)) as amount_earned, 
    referred_at, 
    max(activated_at) as last_activated_at 
    from 
    agents 
    group by id, referred_at), 
    distinct_referrals_by_app_id 
    as 
    (select id, app_id as best_selling_app,
    count(app_id) as best_selling_app_count 
    from agents 
    group by id, app_id ) 
    select *, dense_rank() over (order by best_selling_app_count desc) best_selling_app_rank 
    from distinct_referrals_by_id 
    inner join distinct_referrals_by_app_id 
    on (distinct_referrals_by_id.id = distinct_referrals_by_app_id.id);

这是我得到的结果:

id | activations_count | amount_earned | referred_at | last_activated_at | id | best_selling_app | best_selling_app_count | best_selling_app_rank
----+-------------------+---------------+-------------+-------------------+----+------------------+------------------------+-----------------------
  2 |                 3 |          14.0 |           2 |                 8 |  2 | b                |                      2 |                     1
  1 |                 1 |           6.0 |           1 |                 5 |  1 | b                |                      1 |                     2
  2 |                 3 |          14.0 |           2 |                 8 |  2 | a                |                      1 |                     2
  4 |                 1 |           3.0 |           4 |                 6 |  4 | c                |                      1 |                     2

这个结果的问题是 table 有一个重复的 id 2。我只需要 id 列的唯一值。

我尝试了一种解决方法,即利用 distinct 给出了预期的结果,但我担心查询结果可能不可靠且不一致。 这是解决方法查询:

with agents 
    as 
    (select 
    referrals.id, 
    referral_id, 
    amount_earned, 
    referred_at, 
    activated_at, 
    activations.app_id 
    from referrals 
    left outer join activations 
    on (referrals.id = activations.referral_id) 
    where referrals.user_id_owner = 1), 
    distinct_referrals_by_id 
    as 
    (select 
    id, 
    count(referral_id) as activations_count, 
    sum(coalesce(amount_earned, 0)) as amount_earned, 
    referred_at, 
    max(activated_at) as last_activated_at 
    from 
    agents 
    group by id, referred_at), 
    distinct_referrals_by_app_id 
    as 
    (select 
    distinct on(id), app_id as best_selling_app,
    count(app_id) as best_selling_app_count 
    from agents 
    group by id, app_id 
    order by id, best_selling_app_count desc) 
    select *, dense_rank() over (order by best_selling_app_count desc) best_selling_app_rank 
    from distinct_referrals_by_id 
    inner join distinct_referrals_by_app_id 
    on (distinct_referrals_by_id.id = distinct_referrals_by_app_id.id);

我需要关于如何最好地实现这一目标的建议。

I am trying to generate another table from the two tables that has only unique values for referrals.id and returns as one of the columns the count for each apps as best_selling_app_count.

您的问题非常复杂,SQL 查询非常复杂。但是,以上是实际问题。如果是这样,您可以使用:

select r.*, 
       a.app_id as most_common_app_id,
       a.cnt as most_common_app_id_count
from referrals r left join
     (select distinct on (a.referral_id) a.referral_id, a.app_id, count(*) as cnt
      from activations a
      group by a.referral_id, a.app_id
      order by a.referral_id, count(*) desc
     ) a
     on a.referral_id = r.id;

您没有解释结果集中的其他列。