[英]Sorting by one-to-many relationship and return distinct records
我有一个 ID 列表(page__96de2231 等),我想通过对另一个表的查找进行排序(其中属性 =“p_published_at”,还包括 null 值)。 我只想返回正确排序的 ID。 但是,当对结果 ID 进行区分时,内部查询的顺序会丢失:
SELECT distinct id FROM (
SELECT entity.id, t1.property, t1.postgres_timestamptz
FROM entity
JOIN triple t1
on entity.id = t1.subject
WHERE entity.id IN ('page__96de2231', 'page__1fd94de8', 'page__898f13ec', 'page__81503fa2')
ORDER BY t1.property='p_published_at' DESC NULLS LAST, t1.postgres_timestamptz ASC NULLS LAST
) as inner_query
如何通过改进或重构查询来解决这个问题?
如果您想按特定顺序返回 id,请不要使用子查询。 您需要在最外面的查询中进行排序。
在这种情况下,您可以使用group by
:
SELECT e.id
FROM entity e JOIN
triple t1
ON entity.id = t1.subject
WHERE e.id IN ('page__96de2231', 'page__1fd94de8', 'page__898f13ec', 'page__81503fa2')
GROUP BY e.id
ORDER BY COUNT(*) FILTER (WHERE t1.property = 'p_published_at') DESC NULLS LAST,
MAX(t1.postgres_timestamptz) ASC NULLS LAST;
顺便说一句,您也不需要JOIN
:
SELECT t1.subject as id
FROM triple t1
WHERE t1.subject IN ('page__96de2231', 'page__1fd94de8', 'page__898f13ec', 'page__81503fa2')
GROUP BY t1.subject
ORDER BY COUNT(*) FILTER (WHERE t1.property = 'p_published_at') DESC NULLS LAST,
MAX(t1.postgres_timestamptz) ASC NULLS LAST
一个实体可以有多个三元组。 如果一个实体有两个三元组,一个在列表的开头排序,一个在列表的末尾,您会将实体放在结果中的什么位置? 在开始还是结束?
您可以使用DENSE_RANK
给行排序键。 然后决定是否对每个实体采用最小或最大排序键:
select id
from
(
select
e.id,
dense_rank() over (order by t.property = 'p_published_at' desc nulls last,
t.postgres_timestamptz asc nulls last) as sortkey
from entity e
join triple t on e.id = t.subject
where e.id in ('page__96de2231', 'page__1fd94de8', 'page__898f13ec', 'page__81503fa2')
) ranked
group by id
order by min(sortkey), id;
(当然 Gordon 是对的,您可以从查询中删除表实体;这不是必需的。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.