我正在使用PostgreSQL,但对SQL却一无所获。我的记录很长,想将它们分配到组中,其中组的每个成员与至少一个其他组的成员具有两个相同的列之一。理想情况下,通过创建一个包含来自任一列的所有不同值的表(它们之间完全没有重叠,因为它们是完全不同的字符值)及其所属的组数。
我希望某些组仅由一个成员组成,但是可能存在长链关系,其中两个记录没有连接,而第三条记录将它们连接在一起。使用编程语言(例如JavaScript),我可能会使用递归函数,但是使用SQL时我会迷路。
我尝试寻找答案,但发现很难找到合适的关键词。这有点像一个巨大的多米诺骨牌游戏,但还是有点不同。有没有解决此问题的简单方法?如果没有,有人可以指出我的正确方向吗?
编辑: 一些示例数据。 userId和session是我的两列。因此,在这种情况下,Id 2、4和6将在同一组中。
Id Type userID session 1 callback 25596094 lJcD7fiFCnB4o4ZxI_DQHKMmBGW1T0b4 2 callback 26631605 xupFcU6C8cl7wdviOnc1XX37Feg234vK 3 callback 02-9128924-01 eNE8VuJBz9vffGeuALy72owq1cJhK84l 4 callback 26631605 GhenxfiVXQaGbYq2_SXJhhkvTRN8M3vb 5 callback globetrotter-394146 PdJEDeW57piXMu6nNsJjLZeFmNrP2jvG 6 callback 31831125 xupFcU6C8cl7wdviOnc1XX37Feg234vK
答案 0 :(得分:0)
这只是部分解决方案,它将根据您的逻辑检索与第一个相关的所有行。
在这种情况下,如果我们从行(id = 4)开始,则查询可能是:
with recursive
x as (
select * from my_table where id = 4 -- this is the starting row
union all
select t.*
from my_table t
join x on t.userID = x.userId or t.session = x.session
)
select * from x
结果将是:
Id Type userID session
4 callback 26631605 GhenxfiVXQaGbYq2_SXJhhkvTRN8M3vb
2 callback 26631605 xupFcU6C8cl7wdviOnc1XX37Feg234vK
6 callback 31831125 xupFcU6C8cl7wdviOnc1XX37Feg234vK
查询需要做更多的工作才能使其在所有行中运行,而不仅仅是这种情况下的子集。
更新2018年12月7日:
我编写了一个SQL更新,该更新将找到一个组,并为其分配一个新的(不同的)group_id
值。如果多次运行此SQL更新,最终将为所有行分配组ID。在这里:
alter table my_table add group_id int; -- extra column stores the group_id
create sequence group_id_seq; -- will generate a different group_id each time
with recursive
s as (
select nextval('group_id_seq') as nv
),
x as (
select * from (
select * from my_table where group_id is null fetch first 1 rows only
) x
union
select t.*
from my_table t
join x on t.userid = x.userid or t.session = x.session
)
update my_table t set group_id = s.nv from s, x where t.id = x.id;
同样,每次您运行它时,它将使用新的组ID值标记一组新的[未标记]行。
希望对您有帮助。