私は、おそらくあなたの質問を誤解しているかもしれませんが、場合は約求めている:
どのように多くの人がCAに第1およびOHに旅
次のように(のスケッチ)は、クエリは次のようになります。
scala> trips.show
+------+----+-----+
|tripid|name|state|
+------+----+-----+
| 1|John| OH|
| 2|John| OH|
| 3|John| CA|
| 4|John| OH|
| 1|Mike| CA|
| 2|Mike| CA|
| 3|Mike| OH|
+------+----+-----+
scala> trips.orderBy("name", "tripid").groupBy("name").agg(collect_list("state")).show
+----+-------------------+
|name|collect_list(state)|
+----+-------------------+
|John| [OH, OH, CA, OH]|
|Mike| [CA, CA, OH]|
+----+-------------------+
私は今それを見ると、次の2つのオプションがあるだろう:
を(ハード)書きます集約を行うだろう(と異なる状態が含まれていると思い旅程でcollect_list
に代わる)ユーザ定義の集合関数(UDAF)。
(easy)上記のUDAFと同様のジョブを実行するユーザー定義関数(UDF)を記述します(ただし、collect_list
が値を収集した後)。
(簡単)functions(のようなexplode
および/またはwindow
)を使用し
はのは簡単な解決策やってみましょう(必ずしも最も効果的なの!)。
これは、以前のgroupBy
が本当に必要でないことが判明(!)あなたが(2回使用)だけで、ウィンドウ集計を使用してそれを処理することができます。
import org.apache.spark.sql.expressions.Window
val byName = Window.partitionBy("name").orderBy("tripid")
val distinctStates = trips.withColumn("rank", rank over byName).dropDuplicates("name", "state").orderBy("name", "rank")
scala> distinctStates.show
+------+----+-----+----+
|tripid|name|state|rank|
+------+----+-----+----+
| 1|John| OH| 1|
| 3|John| CA| 3|
| 1|Mike| CA| 1|
| 3|Mike| OH| 3|
+------+----+-----+----+
// rank again but this time use the pre-calculated distinctStates dataset
val distinctStatesRanked = distinctStates.withColumn("rank", rank over byName).orderBy("name", "rank")
scala> distinctStatesRanked.show
+------+----+-----+----+
|tripid|name|state|rank|
+------+----+-----+----+
| 1|John| OH| 1|
| 3|John| CA| 2|
| 1|Mike| CA| 1|
| 3|Mike| OH| 2|
+------+----+-----+----+
val left = distinctStatesRanked.filter($"state" === "OH").filter($"rank" === 1)
val right = distinctStatesRanked.filter($"state" === "CA").filter($"rank" === 2)
scala> left.join(right, "name").show
+----+------+-----+----+------+-----+----+
|name|tripid|state|rank|tripid|state|rank|
+----+------+-----+----+------+-----+----+
|John| 1| OH| 1| 3| CA| 2|
+----+------+-----+----+------+-----+----+
注文を指定する列がない場合は、最初は任意です。 –
こんにちは@vkpここでより具体的なことができますか? –