根据列之间的一对多关系复制行

时间:2018-09-25 16:54:03

标签: sql join apache-spark-sql self-join

这必须是一个已解决的问题,但我不知道要在Google上搜索的正确术语。所以,将在这里解释问题。

我有以下数据集,该数据集具有两个不同的用户标识符(例如id1id2)。

+------+-----+-------+
| id1  | id2 | value |
+------+-----+-------+
| 1    | 11  | blah1 |
| 1    | 12  | blah2 |
| 2    | 13  | blah3 |
| null | 14  | blah4 |
+------+-----+-------+ 

id1id2之间存在一对多关系,因此拥有id2 11和12的用户实际上是同一用户。我想为此类用户复制行,以便将value与每个id2关联。生成的数据集看起来就像

+------+-----+-------+
| id1  | id2 | value |
+------+-----+-------+
| 1    | 11  | blah1 |
| 1    | 12  | blah2 |
| 2    | 13  | blah3 |
| null | 14  | blah4 |
| 1    | 12  | blah1 |
| 1    | 11  | blah2 |
+------+-----+-------+ 

如您所见,值blah1现在与11和12 id2都相关联,值blah2也是如此。

必须有某种self-join可以做到这一点,但是我不知道它是什么(SQL新手)。如果有人能指出我正确的方向,将不胜感激。

2 个答案:

答案 0 :(得分:1)

好吧,您可以自行加入,这是完全允许的... Join将基于键连接链接列(通常) 请注意,在这种情况下,还需要合并,因为您想要更多的行,而不是列

SELECT t.*
FROM
table t
INNER JOIN table t2 ON t.id1 = t2.id1 AND t. id2 != t2.id2

UNION

SELECT t.*
FROM
table t
INNER JOIN table t2 ON t.id1 = t2.id1 AND t. id2 = t2.id2

答案 1 :(得分:0)

为此,您可以使用join生成行:

select i.id1, i.id2, iv.value
from (select distinct id1, value from t) iv join
     (select distinct id1, id2 from t) i 
     on iv.id1 = i.id1 ;

实际上,第二个select distinct可能不是必需的(除非您的原始数据重复,如果您将这些行重新添加到表中,则将是重复的),但是我认为这样会使查询更清晰。这也应该起作用:

select t.id1, t.id2, iv.value
from (select distinct id1, value from t) iv join
     t 
     on iv.id1 = t.id1 ;