如何使用scala获取事务中的第一条记录?

Posted

技术标签:

【中文标题】如何使用scala获取事务中的第一条记录?【英文标题】:How to fetch first record in transaction using scala? 【发布时间】:2017-09-20 06:38:36 【问题描述】:

我的数据看起来像:

我想以最小的出现时间获取每个 dtcode 的第一条记录。

期望的输出:

通过使用 scala 我想获取。 请指导我构建逻辑。

谢谢, 赛姆。

【问题讨论】:

我同意下面的 Jacques Amar 的观点,我认为您可以解决此问题的唯一方法是自己手动遍历整个数据框并检查 dtcode 是否更改。它应该只是简单地做程序本身,但是它不会很有效。如果您可以获得每个组的唯一标识符,那么groupBy() 将是一个简单的选择。 【参考方案1】:

我对您的问题进行了更多思考,并提出了一个更好的解决方案,使用数据帧的 Window 函数。首先,所有内容都由Currentdatedtime 排序,然后检查每一行以查看dtcode 是否已更改。使用您的示例数据:

val spark = SparkSession.builder.getOrCreate()
import spark.implicits._


val df = Seq(("7-1-2016 0:00:17",0),("7-1-2016 0:01:17",0),
    ("7-1-2016 0:02:17",4),("7-1-2016 0:03:17",4),
    ("7-1-2016 0:04:17",0),("7-1-2016 0:05:17",0),
    ("7-1-2016 0:06:17",0),("7-1-2016 0:07:17",5)).toDF("Currentdatedtime", "dtcode")

val w = Window.orderBy("Currentdatedtime")
val df2 = df.withColumn("dtcode_change",
   when(lag($"dtcode", 1).over(w) === $"dtcode", 0).
   otherwise(1))
 .filter($"dtcode_change" === 1)
 .drop("dtcode_change")

会给你:

+----------------+------+
|Currentdatedtime|dtcode|
+----------------+------+
|7-1-2016 0:00:17|     0|
|7-1-2016 0:02:17|     4|
|7-1-2016 0:04:17|     0|
|7-1-2016 0:07:17|     5|
+----------------+------+

【讨论】:

【参考方案2】:

--- 用 Shaido 的正确评论编辑---

通常,如果表中的顺序无关紧要,GROUP BY 会处理这个问题,

SQL 擅长对大量相关数据进行分组。但是,您的分析取决于数据输入的顺序,并且更改由一列中的更改触发,该更改可以稍后重复且无法聚合,而其他列可以继续更改。

在这种情况下,您需要对数据进行循环并手动检测更改,因为 SQL 没有简单的方法来对此类事物进行分组。我回答有点太快了,并没有注意到这一点。

最好通过存储过程或显示语言来处理。如果你愿意,我可以给你 php 的代码。

另一个作弊方法是添加一个 GROUP BY 使用的列(我们称之为groubycheat),每次dtcode 更改时都会增加

SELECT MIN(Currentdatedtime) as Currentdatedtime, dtcode
FROM <tablename>
GROUP BY groupbycheat;

这个 STILL 需要一个 LOOP 来添加字段,但是如果你需要多次获取结果,那么它是值得的。否则..没有

【讨论】:

groupBy 在这里不起作用,因为 dtcode 对于每个组来说不是唯一的。再次检查给出的示例,有两个组为 0。 感谢 shaido 的回复。我不想要 SQL 或 Scala 我不知道 PHP。这些数据需要从 HDFS 中获取。

以上是关于如何使用scala获取事务中的第一条记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用聚合函数在 MySQL 查询中获取分组记录的第一条和最后一条记录?

Extjs4 - 如何从商店的第一条记录中获取价值

mysql中如何查询表的第一条和最后一条记录

如何识别列中的第一条记录 pysaprk

在 PySpark RDD 中,如何使用 foreachPartition() 打印出每个分区的第一条记录?

如何使用 MS Access 中的从句获取 MAX 值