在SparkSQL连接中无法解析列名

时间:2016-10-03 13:42:33

标签: pyspark apache-spark-sql pyspark-sql

我不确定为什么会这样。在PySpark中,我读入两个数据帧并打印出它们的列名,它们是预期的,但是当进行SQL连接时,我得到一个错误,在给定输入的情况下无法解析列名。我简化了合并只是为了让它工作,但我需要添加更多的连接条件,这就是我使用SQL的原因(将添加:“和b.mnvr_bgn< a.idx_trip_id和b.mnvr_end > a.idx_trip_data“)。看来df mnvr_temp_idx_prev_temp

中的'device_id'列被重命名为'_col7'
mnvr_temp_idx_prev = mnvr_3.select('device_id', 'mnvr_bgn', 'mnvr_end')
print mnvr_temp_idx_prev.columns
['device_id', 'mnvr_bgn', 'mnvr_end']

raw_data_filtered = raw_data.select('device_id', 'trip_id', 'idx').groupby('device_id', 'trip_id').agg(F.max('idx').alias('idx_trip_end'))
print raw_data_filtered.columns
['device_id', 'trip_id', 'idx_trip_end']

raw_data_filtered.registerTempTable('raw_data_filtered_temp')
mnvr_temp_idx_prev.registerTempTable('mnvr_temp_idx_prev_temp') 
test = sqlContext.sql('SELECT a.device_id, a.idx_trip_end, b.mnvr_bgn, b.mnvr_end \
                          FROM raw_data_filtered_temp as a  \
                             INNER JOIN mnvr_temp_idx_prev_temp as b \
                                ON a.device_id = b.device_id')

Traceback(最近一次调用最后一次):AnalysisException:u“无法解析给定输入列的'b.device_id':[_ col7,trip_id,device_id,mnvr_end,mnvr_bgn,idx_trip_end]; line 1 pos 237”

感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

我建议至少在一个数据框中重命名字段'device_id'的名称。我稍微修改了你的查询并测试了它(在scala中)。以下查询工作

test = sqlContext.sql("select * FROM raw_data_filtered_temp a INNER JOIN mnvr_temp_idx_prev_temp b ON a.device_id = b.device_id")
[device_id: string, mnvr_bgn: string, mnvr_end: string, device_id: string, trip_id: string, idx_trip_end: string]

现在如果您在上面的语句中执行'select *',它将起作用。但是如果你试图选择'device_id',你会收到一个错误“参考'device_id'是不明确的”。正如您在上面的'test'数据框定义中所看到的,它有两个具有相同名称的字段(device_id)。因此,为了避免这种情况,我建议在其中一个数据帧中更改字段名称。

mnvr_temp_idx_prev = mnvr_3.select('device_id', 'mnvr_bgn', 'mnvr_end')
                           .withColumnRenamned("device_id","device")  

raw_data_filtered = raw_data.select('device_id', 'trip_id', 'idx').groupby('device_id', 'trip_id').agg(F.max('idx').alias('idx_trip_end'))

现在使用dataframes或sqlContext

//using dataframes with multiple conditions
  val test = mnvr_temp_idx_prev.join(raw_data_filtered,$"device" === $"device_id"
                                                   && $"mnvr_bgn" < $"idx_trip_id","inner")

//在SQL上下文中

 test = sqlContext.sql("select * FROM raw_data_filtered_temp a INNER JOIN mnvr_temp_idx_prev_temp b ON a.device_id = b.device and a. idx_trip_id < b.mnvr_bgn")

以上查询适用于您的问题。如果您的数据集太大,我建议不要使用'&gt;'或'&lt;'连接条件中的运算符,因为它会导致交叉连接,如果数据集很大,这是一项代价高昂的操作而是在WHERE条件中使用它们。