如何使用 DISTINCT ON 但 ORDER BY 另一个表达式?
How to use DISTINCT ON but ORDER BY another expression?
模特Subscription
has_many
SubscriptionCart
.
A SubscriptionCart
有一个 status
和一个 authorized_at
日期。
我需要从与 Subscription
关联的所有购物车中选择日期最旧的 authorized_at
购物车,然后我必须通过此命令对所有返回的 Subscription
结果进行排序subscription_carts.authorized_at
列。
下面的查询有效,但我不知道如何 select 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 ON
和 ORDER BY
表达式必须按相同的顺序。
我找到的解决方案似乎对我的需要来说太复杂了,但我未能实施它们,因为我不完全理解它们。
GROUP BY subscription_id
然后从该组中选择而不是使用 DISTINCT ON
会更好吗?任何帮助表示赞赏。
此要求是使 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;
您不必使用 DISTINCT ON
。虽然它偶尔有用,但我个人发现 window 基于函数的方法更加清晰:
-- 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
模特Subscription
has_many
SubscriptionCart
.
A SubscriptionCart
有一个 status
和一个 authorized_at
日期。
我需要从与 Subscription
关联的所有购物车中选择日期最旧的 authorized_at
购物车,然后我必须通过此命令对所有返回的 Subscription
结果进行排序subscription_carts.authorized_at
列。
下面的查询有效,但我不知道如何 select 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 ON
和 ORDER BY
表达式必须按相同的顺序。
我找到的解决方案似乎对我的需要来说太复杂了,但我未能实施它们,因为我不完全理解它们。
GROUP BY subscription_id
然后从该组中选择而不是使用 DISTINCT ON
会更好吗?任何帮助表示赞赏。
此要求是使 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;
您不必使用 DISTINCT ON
。虽然它偶尔有用,但我个人发现 window 基于函数的方法更加清晰:
-- 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