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