[英]How to get distinct column and show one to many relation in a postgresql query
[英]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.