簡體   English   中英

Postgresql,如何在一次傳遞表中為每個不同的 relation_id 值獲取一行?

[英]Postgresql, how get one row for each distinct relation_id value in one pass over table?

例如,我們有表:

ID 價值 關系編號
1個 價值1 1個
2個 值2 2個
3個 價值3 1個
4個 值4 1個
5個 值5 3個

例如,我想要獲取 ID 為 1、2、5 的行(因為它們具有不同的 relation_id 值)。 這很容易,但如果您有數十億行則不然。 即使在 SSD 驅動器上也很慢。 我有 relation_id 的每個可能值,我嘗試了這樣的查詢:

(select value, relation_id from table where relation_id=2 limit 1)
union
(select value, relation_id from table where relation_id=3 limit 1)
-- so on

但事實證明,對於每個子查詢 postgresql 從一開始就在表中查找,盡管它是一個查詢。 有沒有辦法以這種方式編寫查詢,即 postgresql 單次傳遞表並沿途收集所需數據?

方法 1 :使用 PostgreSQL DISTINCT ON運算符。 給定ORDER BY子句,它將僅匹配括號內字段的不同值,以防止重復。

SELECT DISTINCT ON(relation_id) id_, value_, relation_id
FROM tab
ORDER BY relation_id

此處查看演示。


方法 2 :使用ROW_NUMBER window function 對按“ relation_id ”分區的記錄生成排名,然后 select 每個關系的第一條記錄(rownum = 1)

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER(PARTITION BY relation_id ORDER BY id_) AS rn 
    FROM tab
)
SELECT id_, value_, relation_id 
FROM cte
WHERE rn = 1

此處查看演示。


方法 3 :在過濾結構中使用ROW_NUMBER FETCH FIRST ROWS WITH TIES ,這將充當方法 2 但避免了子查詢(獲取綁定行,綁定在 rownum=1 上)。

SELECT *
FROM tab
ORDER BY ROW_NUMBER() OVER(PARTITION BY relation_id ORDER BY id_) = 1 DESC
FETCH FIRST 1 ROWS WITH TIES

此處查看演示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM