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

时间:2017-09-20 06:38:37

标签: mysql scala apache-spark-sql hiveql impala

我的数据看起来像:

enter image description here

我想以迷你发生时间获取每个dtcode的第一条记录。

期望的输出:

enter image description here

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

谢谢, SYAM。

2 个答案:

答案 0 :(得分:0)

---来自Shaido的正确评论已编辑---

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

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

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

最好通过STORED PROCEDURE或显示语言来处理。如果你愿意,我可以用PHP给你代码。

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

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

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

答案 1 :(得分:0)

我更多地考虑了您的问题,并使用数据框的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|
+----------------+------+