繁体   English   中英

按一对多关系排序并返回不同的记录

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM