Postgresql
在連接上生成序列號
對於 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 in
place_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 的功能!