sql - 不使用内部联接的 Sql 查询
问题描述
我有一个火花数据集输入DS 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
time
最终目标是根据 MAX( ) 列获取每个 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) 如果我们能够从步骤 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.*");
解决方案
这是您当前连接查询的变体,它依赖于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;
分析函数通常可以击败较老的方法,例如联接。
推荐阅读
- javascript - 如何使用测试从 Postman 中的 JSON 响应中提取特定值?
- regex - 使用 grep 在第一次或第二次出现四位数字字符串后删除文本。带连字符的文本问题
- flutter - 项目更改时,DropdownButton 不会重新呈现菜单
- laravel-7 - 使用自定义字段进行 Cartalyst Sentinel 用户注册(已解决)
- c - 使用枚举的日历
- python - 方法返回 TypeError:列表索引必须是整数或切片,而不是 str
- outlook - ThisOutlookSession Public WithEvents 变量不再公开
- windows - 将属性应用于 Windows 10 快捷方式时,值不在预期范围内
- r - 使用来自单独数据框的值重命名列
- java - 里面有 Jar 的 Maven 神器