Postgresql

在連接上生成序列號

  • September 12, 2022

對於 JOIN 中的每個右側行,我想創建一個序列號,從每個左側行的 1(或 0)開始。

例子:

create table persons (person_id int, person_name text);
create table places (place_id int, person_id int, place_name text);
insert into persons values (10, 'Aulus Agerius'), (20, 'Numerius Negidius');
insert into places values (10, 10, 'Anytown'), (20, 10, 'Timbuktu'), (30, 20, 'Podunk');
select person_name, place_name
from persons join places using (person_id)
order by person_id, place_id;

小提琴

期望的結果:

因此,例如 2 inplace_seq表示“這是為這個人找到的第二個地方”。

如何創建place_seq列?

您需要ROW_NUMBER()手動)視窗功能如下(下面的程式碼顯示在小提琴上- 基於您自己的小提琴+1!)

SELECT 
 person_id,
 place_id,
 person_name, 
 place_name, 
 ROW_NUMBER() 
   OVER (PARTITION BY person_id ORDER BY place_id) AS rn
FROM persons 
 JOIN places using (person_id)
ORDER BY person_id, place_id;

這是基於person_id&place_id至少UNIQUE或(更好)PRIMARY KEY各自表的 s 的假設。可以想像,兩個人可以有相同的名字——我知道兩組三個人(獨立 - 不是同一個家庭)同名。至於地方,重複更為常見。

結果:

person_name       place_name    rn
Aulus Agerius        Anytown     1
Aulus Agerius       Timbuktu     2
Numerius Negidius     Podunk     1

為了保證在不同的執行中獲得一致的結果,ORDER BY視窗函式中的確定性子句是必要的。ORDER BY通常,如果我們希望結果具有確定性順序,SQL 語句應該包含一個,視窗函式也應該包含。

對於視窗函式,另請參見此處此處。這些功能非常強大,將回報您多次學習它們所付出的努力。網路上到處都有關於它們的文章——我敦促你四處看看並練習,直到你(一定程度上)掌握它們。

作為第一個停靠點,我強烈推薦 Bruce Momjian 在此處的 YouTube 展示文稿此處為幻燈片)。Bruce Momjian 是EnterpriseDB(全球首屈一指的 PostgreSQL 公司)的副總裁和“Postgres 傳播者”。他也是一位出色的演講者,並且很好地解釋了 PostgreSQL 的功能!

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