2017-05-03 4 views
2

私はこのようになりますテーブルを持っている:相互に関連する条件に一致する行を数えるには?

TripID | Name | State 
    1  | John | OH  
    2  | John | OH 
    3  | John | CA 
    4  | John | OH 
    1  | Mike | CA 
    2  | Mike | CA 
    3  | Mike | OH 

私はOHに旅の人々まず、CAに続いてカウントしたいのですが

上記の場合には、それだけでそう答えは1

あるべきジョンだろうだから私たちは結果をフィルタリングするためにSQLフィルタで特定の順序を設定する方法を知りたいですか?

+1

注文を指定する列がない場合は、最初は任意です。 –

+0

こんにちは@vkpここでより具体的なことができますか? –

答えて

2

私は、おそらくあなたの質問を誤解しているかもしれませんが、場合は約求めている:

どのように多くの人が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つのオプションがあるだろう:

  1. を(ハード)書きます集約を行うだろう(と異なる状態が含まれていると思い旅程でcollect_listに代わる)ユーザ定義の集合関数(UDAF)。

  2. (easy)上記のUDAFと同様のジョブを実行するユーザー定義関数(UDF)を記述します(ただし、collect_listが値を収集した後)。

  3. (簡単)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| 
+----+------+-----+----+------+-----+----+ 
関連する問題