2

模型Subscription has_many SubscriptionCart

ASubscriptionCart有一个status和一个authorized_at日期。

我需要authorized_at从与 a 关联的所有购物车中选择日期最早的购物车Subscription,然后我必须按此列对所有返回的Subscription结果进行排序。subscription_carts.authorized_at

下面的查询正在运行,但我不知道如何选择DISTINCT ON subscription.id以避免重复,但是ORDER BY subscription_carts.authorized_at.

到目前为止的原始 sql 查询:

select distinct on (s.id) s.id as subscription_id, subscription_carts.authorized_at, s.*
from subscriptions s
join subscription_carts subscription_carts on subscription_carts.subscription_id = s.id 
and subscription_carts.plan_id = s.plan_id
where subscription_carts.status = 'processed'
and s.status IN ('authorized','in_trial', 'paused')
order by s.id, subscription_carts.authorized_at

如果我先尝试ORDER BY subscription_carts.authorized_at,我会得到一个错误,因为DISTINCT ONandORDER BY表达式的顺序必须相同。

我发现的解决方案对于我需要的东西来说似乎太复杂了,而且我没有实施它们,因为我不完全理解它们。

GROUP BY subscription_id然后从该组中选择而不是使用会更好DISTINCT ON吗?任何帮助表示赞赏。

4

2 回答 2

0

您不必使用DISTINCT ON. 虽然它偶尔有用,但我个人发现基于窗口函数的方法更加清晰:

-- Optionally, list all columns explicitly, to remove the rn column again
SELECT *
FROM (
  SELECT
    s.id AS subscription_id,
    c.authorized_at,
    s.*,
    ROW_NUMBER () OVER (PARTITION BY s.id ORDER BY c.authorized_at) rn
  FROM subscriptions s
  JOIN subscription_carts c
  ON c.subscription_id = s.id
  AND c.plan_id = s.plan_id
  WHERE c.status = 'processed'
  AND s.status IN ('authorized', 'in_trial', 'paused')
) t
WHERE rn = 1
ORDER BY subscription_id, authorized_at
于 2021-11-24T13:20:15.070 回答
0

这个要求是DISTINCT ON工作所必需的;要更改最终顺序,您可以添加带有另一个ORDER BY子句的外部查询:

SELECT *
FROM (SELECT DISTINCT ON (s.id)
             s.id as subscription_id, subscription_carts.authorized_at, s.*
      FROM subscriptions s
         JOIN ...
      WHERE ...
      ORDER BY s.id, subscription_carts.authorized_at
     ) AS subq
ORDER BY authorized_at;
于 2021-11-24T13:14:24.903 回答