对于 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;
期望的结果:
人名 | 地名 | place_seq |
---|---|---|
奥卢斯·艾格瑞斯 | 任何城镇 | 1 |
奥卢斯·艾格瑞斯 | 廷巴克图 | 2 |
努梅里乌斯·内吉迪乌斯 | 波敦克 | 1 |
因此,例如 2 inplace_seq
表示“这是为这个人找到的第二个地方”。
如何创建place_seq
列?
您需要
ROW_NUMBER()
(手动)窗口功能如下(下面的代码显示在小提琴上- 基于您自己的小提琴+1!):这是基于
person_id
&place_id
至少UNIQUE
或(更好)PRIMARY KEY
各自表的 s 的假设。可以想象,两个人可以有相同的名字——我知道两组三个人(独立 - 不是同一个家庭)同名。至于地方,重复更为常见。结果:
为了保证在不同的运行中获得一致的结果,
ORDER BY
窗口函数中的确定性子句是必要的。ORDER BY
通常,如果我们希望结果具有确定性顺序,SQL 语句应该包含一个,窗口函数也应该包含。对于窗口函数,另请参见此处和此处。这些功能非常强大,将回报您多次学习它们所付出的努力。网络上到处都有关于它们的文章——我敦促你四处看看并练习,直到你(一定程度上)掌握它们。
作为第一个停靠点,我强烈推荐 Bruce Momjian 在此处的 YouTube 演示文稿(此处为幻灯片)。Bruce Momjian 是EnterpriseDB(全球首屈一指的 PostgreSQL 公司)的副总裁和“Postgres 传播者”。他也是一位出色的演讲者,并且很好地解释了 PostgreSQL 的功能!