Postgresql

是否可以按輸入 ID 的順序排序?

  • September 27, 2021

我想找到使用者最喜歡的音樂列表。第一步,我id從使用者favorite表中查詢所有內容。在下一步中,我通過表查詢音樂id列表songs。但現在我想按時間戳列favorite.added_atdesc 對行進行排序。

我不想加入表,所以我想弄清楚是否可以按 in 查詢中的輸入 id 進行排序。

例如:

-- the 3087 is first record
select *
from songs s 
where id in (3087,5122)

-- the 5122 is first record
select *
from songs s 
where id in (5122,3087)

我已經在 PostgreSQL 13 中嘗試過,並且id = 3087總是排在第一位。似乎 PostgreSQL 不按IN列表中的值序列獲取行?

您的方法存在一個根本缺陷,即您首先選擇收藏夾,然後在第二個查詢中獲取歌曲詳細資訊。您不僅缺少ORDER BY第二個查詢的好子句,而且將這樣的任務拆分為兩個查詢會導致不必要的工作。

通過在連接兩個表的單個查詢中解決完整問題,您可以提高性能並一步解決您的問題。那麼這個ORDER BY子句就自然而然了。

排序

似乎 PostgreSQL 不按IN列表中的值序列獲取行?

傳遞給的值的順序IN無關緊要的。Postgres 可以自由地以任意順序返回行,除非用ORDER BY.

您可以傳遞一個集合併添加一個“排序”列。

但是傳遞一個數組並使用給定的元素順序要簡單得多。使用unnest()並附加WITH ORDINALITY

-- 3087 first
SELECT s.*
FROM   unnest('{3087,5122}'::int[]) WITH ORDINALITY AS i(id, ord)
JOIN   song s USING (id)
ORDER  BY ord;

db<>在這裡擺弄

看:

另一個重要區別:雖然IN列表(或集合)中的重複項被刪除,但在加入非嵌套數組時它們保持原樣。

適當的解決方案

假設兩個表 (favoritesongs) 駐留在同一個數據庫中,執行單個查詢會更好:

SELECT s.*
FROM   favorite f
JOIN   song s ON s.id = f.song_id
WHERE  f.user_id = 123
ORDER  BY f.added_at DESC;

然後就可以favorite.added_at直接下單了。這是到數據庫伺服器的一次往返。

引用自:https://dba.stackexchange.com/questions/300170