如何基于具有相同ID的另一行更新一行

时间:2018-12-24 07:16:08

标签: apache-spark-sql

对于Spark数据框,我想基于具有相同ID的其他行来更新行值。

例如, 我在下面有记录,

id,value
1,10
1,null
1,null
2,20
2,null
2,null

我想得到如下结果

id,value
1,10
1,10
1,10
2,20
2,20
2,20

总结一下,值列在某些行中为空,如果还有另一行具有相同ID且具有有效值的行,我想对其进行更新。

在sql中,我可以使用inner-join编写一个更新语句,但是在Spark-sql中找不到相同的方法。

更新CombineCols a   内部联接CombineCols b     在a.id = b.id上 设置a.value = b.value (这是我在sql中的操作方式)

2 个答案:

答案 0 :(得分:1)

让我们使用SQL方法解决此问题-

@Bean
public ServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
        @Override
        protected void postProcessContext(Context context) {
            SecurityConstraint securityConstraint = new SecurityConstraint();
            securityConstraint.setUserConstraint("CONFIDENTIAL");
            SecurityCollection collection = new SecurityCollection();
            collection.addPattern("/*");
            securityConstraint.addCollection(collection);
            context.addConstraint(securityConstraint);
        }
    };
    tomcat.addAdditionalTomcatConnectors(redirectConnector());
    return tomcat;
}

private Connector redirectConnector() {
    Connector connector = new Connector(
            TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
    connector.setScheme("http");
    connector.setPort(8080);
    connector.setSecure(false);
    connector.setRedirectPort(8443);
    return connector;
}

注意事项:该代码假定任何特定myValues = [(1,10),(1,None),(1,None),(2,20),(2,None),(2,None)] df = sqlContext.createDataFrame(myValues,['id','value']) df.registerTempTable('table_view') df1=sqlContext.sql( 'select id, sum(value) over (partition by id) as value from table_view' ) df1.show() +---+-----+ | id|value| +---+-----+ | 1| 10| | 1| 10| | 1| 10| | 2| 20| | 2| 20| | 2| 20| +---+-----+ 的值只有一个non-null。当我们使用id值时,我们必须使用groupby函数,而我已经使用了aggregation。如果任何sum都有2个non-null值,则将对进行汇总。如果id可以有多个id值,那么最好使用non-null,以便我们获得其中一个值而不是min/max

sum

答案 1 :(得分:0)

您可以使用window来执行此操作(在pyspark中):

from pyspark.sql import functions as F
from pyspark.sql.window import Window

# create dataframe
df = sc.parallelize([
    [1,10],
    [1,None],
    [1,None],
    [2,20],
    [2,None],
    [2,None],
]).toDF(('id', 'value'))

window = Window.partitionBy('id').orderBy(F.desc('value'))
df \
    .withColumn('value', F.first('value').over(window)) \
    .show()

结果:

+---+-----+
| id|value|
+---+-----+
|  1|   10|
|  1|   10|
|  1|   10|
|  2|   20|
|  2|   20|
|  2|   20|
+---+-----+

您可以在scala中使用相同的功能。