我有如下所示的spark数据集inputDS Dataset<Row>
+---------------+---------------+----------------+-------+--------------+--------+
| time | thingId | controller | module| variableName | value |
+---------------+---------------+----------------+-------+--------------+--------+
|1554188276412 | 0002019000000| 0 | 0 |Voltage | 9 |
|1554188639406 | 0002019000000| 0 | 0 |SetPoint | 6 |
+---------------+---------------+----------------+-------+--------------+--------+
由 STEP 1
生成Dataset<Row> inputDS = readInput.groupby("thingId","controller","module","variableName").agg(max(struct("time","value")).as("time_value_struct")).select("thingId","controller","module","variableName","time_value_struct.*");
预期产量
+---------------+---------------+----------------+-------+--------------+--------+
| time | thingId | controller | module| variableName | value |
+---------------+---------------+----------------+-------+--------------+--------+
|1554188639406 | 0002019000000| 0 | 0 |Voltage | 9 |
|1554188639406 | 0002019000000| 0 | 0 |SetPoint | 6 |
+---------------+---------------+----------------+-------+--------------+--------+
该Max(time)
的 thingId,controller,module and variableName
列
最终目标是基于MAX({time
)列获取每个thingId,控制器,模块和变量名的最后更新值。
代码
inputDS.createOrReplaceTempView("intermediate");
Dataset<Row> outputDS = spark.sql("select B.time,A.thingId,A.controller,A.module,A.variableName,A.value from intermediate A
inner join (select thingId,controller,module,MAX(time)time from intermediate group by thingId,controller,module) B
on A.thingId=B.thingId and A.controller=B.controller and A.module=B.module");
SQL查询可以正常工作,但是使用inner join
看起来效率不高
1)还有什么其他有效的方法可以在没有内部联接或等价条件的情况下获得预期的输出。
2)如果能够从 STEP 1
获得预期的输出,那就太好了 Dataset<Row> intermediate = inputDS.groupby("thingId","controller","module","variableName").agg(max(struct("time","value")).as("time_value_struct")).select("thingId","controller","module","variableName","time_value_struct.*");
答案 0 :(得分:2)
这是您当前的联接查询的一种变体,它依赖于ROW_NUMBER
:
SELECT time, thingId, controller, module, variableName, "value"
FROM
(
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY thingId, controller, module
ORDER BY time DESC) rn
FROM intermediate
) t
WHERE rn = 1;
分析功能通常可以击败老式的方法,例如加入。