2017-05-31 2 views
1

私はスパークSQLを使用して、私はconsecutivesの最も長いシーケンスは、私が適応しようとしたどのように連続した日付の最長シーケンスを見つけるのですか?

ID, longest_seq (days) 
1, 2 
2, 5 
3, 1 

のように、各IDの日付持っている必要があり、この

ID, time 
1, 1493596800 
1, 1493596900 
1, 1493432800 
2, 1493596800 
2, 1493596850 
2, 1493432800 

のようなタイムスタンプの時間の訪問でデータベースを持っていますこの回答Detect consecutive dates ranges using SQL私の場合には、私は私が期待していることを管理していませんでした。

SELECT ID, MIN (d), MAX(d) 
    FROM (
     SELECT ID, cast(from_utc_timestamp(cast(time as timestamp), 'CEST') as date) AS d, 
       ROW_NUMBER() OVER(
     PARTITION BY ID ORDER BY cast(from_utc_timestamp(cast(time as timestamp), 'CEST') 
                  as date)) rn 
     FROM purchase 
     where ID is not null 
     GROUP BY ID, cast(from_utc_timestamp(cast(time as timestamp), 'CEST') as date) 
    ) 
    GROUP BY ID, rn 
    ORDER BY ID 

誰かがこの要求を解決する方法についていくつかの手掛かりを持っている、またはそれで間違っているものをした場合、私は おかげ

助けをいただければ幸いですが、[EDIT]より明示的な入力/出力

ID, time 
1, 1 
1, 2 
1, 3 
2, 1 
2, 3 
2, 4 
2, 5 
2, 10 
2, 11 
3, 1 
3, 4 
3, 9 
3, 11 

結果は次のようになります。

ID, MaxSeq (in days) 
1,3 
2,3 
3,1 

すべての訪問でありますタイムスタンプが必要ですが、連続した日が必要ですが、1日に1回の訪問は1日1回カウントされます。

+0

もっと具体的な入力ができますか?私は、入力データセットが結果と一致するとは思わない。 –

答えて

0

これは私の最愛のウィンドウ集合関数のケースです!

私は以下の例があなたを助けてくれると思います(少なくとも始めてください)。

私が使用しているデータセットは次のとおりです。私はあなたの時間をロングタイムで数値に変換して、その日を示しました。そして、Spark SQLのタイムスタンプを使いこなすことで、ソリューションを理解しにくくなる可能性があります。)。

scala> visits.show 
+---+----+ 
| ID|time| 
+---+----+ 
| 1| 1| 
| 1| 1| 
| 1| 2| 
| 1| 3| 
| 1| 3| 
| 1| 3| 
| 2| 1| 
| 3| 1| 
| 3| 2| 
| 3| 2| 
+---+----+ 

ウィンドウの仕様を定義して、idの行をまとめてグループ化しましょう。

import org.apache.spark.sql.expressions.Window 
val idsSortedByTime = Window. 
    partitionBy("id"). 
    orderBy("time") 

これで、あなたはrankと同じランクの行とカウント行を作成できます。

val answer = visits. 
    select($"id", $"time", rank over idsSortedByTime as "rank"). 
    groupBy("id", "time", "rank"). 
    agg(count("*") as "count") 
scala> answer.show 
+---+----+----+-----+ 
| id|time|rank|count| 
+---+----+----+-----+ 
| 1| 1| 1| 2| 
| 1| 2| 3| 1| 
| 1| 3| 4| 3| 
| 3| 1| 1| 1| 
| 3| 2| 2| 2| 
| 2| 1| 1| 1| 
+---+----+----+-----+ 

解決策には(非常に近い)と表示されます。 あなたは完了したようです!

+0

助けてくれてありがとう 私は、ID、時間、およびランクでカウントを使用するかどうかはわかりませんが、id、dayによる訪問回数を表していますか?それではなぜランク関数を使うべきですか? – Farah

1

私の答えは、https://dzone.com/articles/how-to-find-the-longest-consecutive-series-of-evenのSpark SQLでの使用に適合しています。最初のクエリのために、そう

spark.sql(""" 
SQL_QUERY 
""") 

:あなたはしてSQLクエリラップを持っています

CREATE TABLE intermediate_1 AS 
SELECT 
    id, 
    time, 
    ROW_NUMBER() OVER (PARTITION BY id ORDER BY time) AS rn, 
    time - ROW_NUMBER() OVER (PARTITION BY id ORDER BY time) AS grp 
FROM purchase 

これはあなたを与える:

id, time, rn, grp 
1, 1, 1, 0 
1, 2, 2, 0 
1, 3, 3, 0 
2, 1, 1, 0 
2, 3, 2, 1 
2, 4, 3, 1 
2, 5, 4, 1 
2, 10, 5, 5 
2, 11, 6, 5 
3, 1, 1, 0 
3, 4, 2, 2 
3, 9, 3, 6 
3, 11, 4, 7 

を私たちは、連続した行ことがわかります同じgrp値を持つ。次に、GROUP BYとCOUNTを使用して連続時間の数を取得します。

CREATE TABLE intermediate_2 AS 
SELECT 
    id, 
    grp, 
    COUNT(*) AS num_consecutive 
FROM intermediate_1 
GROUP BY id, grp 

これが返されます:

id, grp, num_consecutive 
1, 0, 3 
2, 0, 1 
2, 1, 3 
2, 5, 2 
3, 0, 1 
3, 2, 1 
3, 6, 1 
3, 7, 1 

今、私たちはただ、連続する時間の最大数を取得するにはMAXとGROUP BYを使用します。

あなたを与えるだろう
CREATE TABLE final AS 
SELECT 
    id, 
    MAX(num_consecutive) as max_consecutive 
FROM intermediate_2 
GROUP BY id 

id, max_consecutive 
1, 3 
2, 3 
3, 1 

は、この情報がお役に立てば幸い!

関連する問題