Mysql 在SparkSQL中使用窗口函数(densite_rank())进行选择

Mysql 在SparkSQL中使用窗口函数(densite_rank())进行选择,mysql,sql,apache-spark-sql,dense-rank,Mysql,Sql,Apache Spark Sql,Dense Rank,我有一个表,其中包含客户购买的记录,我需要指定购买是在特定的日期时间窗口中进行的,一个窗口为8天,因此,如果我今天购买,5天内购买,如果窗口号为1,则表示我的购买,但如果我在今天的第一天和8天内的下一天购买,第一次购买将在窗口1中,最后一次购买将在窗口2中 create temporary table transactions (client_id int, transaction_ts datetime, store_id int) insert into transactions

我有一个表,其中包含客户购买的记录,我需要指定购买是在特定的日期时间窗口中进行的,一个窗口为8天,因此,如果我今天购买,5天内购买,如果窗口号为1,则表示我的购买,但如果我在今天的第一天和8天内的下一天购买,第一次购买将在窗口1中,最后一次购买将在窗口2中

create temporary table transactions
 (client_id int,
 transaction_ts datetime,
 store_id int)

 insert into transactions values 
 (1,'2018-06-01 12:17:37', 1),
 (1,'2018-06-02 13:17:37', 2),
 (1,'2018-06-03 14:17:37', 3),
 (1,'2018-06-09 10:17:37', 2),
 (2,'2018-06-02 10:17:37', 1),
 (2,'2018-06-02 13:17:37', 2),
 (2,'2018-06-08 14:19:37', 3),
 (2,'2018-06-16 13:17:37', 2),
 (2,'2018-06-17 14:17:37', 3)
窗口是8天,问题是我不知道如何指定分区上的稠密_秩来查看datetime并在8天内创建一个窗口, 因此,我需要这样的东西

1,'2018-06-01 12:17:37', 1,1
1,'2018-06-02 13:17:37', 2,1
1,'2018-06-03 14:17:37', 3,1
1,'2018-06-09 10:17:37', 2,2
2,'2018-06-02 10:17:37', 1,1
2,'2018-06-02 13:17:37', 2,1
2,'2018-06-08 14:19:37', 3,2
2,'2018-06-16 13:17:37', 2,3
2,'2018-06-17 14:17:37', 3,3
知道怎么弄吗?我可以在Mysql或Spark SQL中运行它,但Mysql不支持分区。
还是找不到解决办法!任何帮助

您都可以使用时间和分区窗口函数在Spark SQL中解决此问题:

val purchases = Seq((1,"2018-06-01 12:17:37", 1), (1,"2018-06-02 13:17:37", 2), (1,"2018-06-03 14:17:37", 3), (1,"2018-06-09 10:17:37", 2), (2,"2018-06-02 10:17:37", 1), (2,"2018-06-02 13:17:37", 2), (2,"2018-06-08 14:19:37", 3), (2,"2018-06-16 13:17:37", 2), (2,"2018-06-17 14:17:37", 3)).toDF("client_id", "transaction_ts", "store_id")

purchases.show(false)
+---------+-------------------+--------+
|client_id|transaction_ts     |store_id|
+---------+-------------------+--------+
|1        |2018-06-01 12:17:37|1       |
|1        |2018-06-02 13:17:37|2       |
|1        |2018-06-03 14:17:37|3       |
|1        |2018-06-09 10:17:37|2       |
|2        |2018-06-02 10:17:37|1       |
|2        |2018-06-02 13:17:37|2       |
|2        |2018-06-08 14:19:37|3       |
|2        |2018-06-16 13:17:37|2       |
|2        |2018-06-17 14:17:37|3       |
+---------+-------------------+--------+



val groupedByTimeWindow = purchases.groupBy($"client_id", window($"transaction_ts", "8 days")).agg(collect_list("transaction_ts").as("transaction_tss"), collect_list("store_id").as("store_ids"))

val withWindowNumber = groupedByTimeWindow.withColumn("window_number", row_number().over(windowByClient))

withWindowNumber.orderBy("client_id", "window.start").show(false)

    +---------+---------------------------------------------+---------------------------------------------------------------+---------+-------------+
|client_id|window                                       |transaction_tss                                                |store_ids|window_number|
+---------+---------------------------------------------+---------------------------------------------------------------+---------+-------------+
|1        |[2018-05-28 17:00:00.0,2018-06-05 17:00:00.0]|[2018-06-01 12:17:37, 2018-06-02 13:17:37, 2018-06-03 14:17:37]|[1, 2, 3]|1            |
|1        |[2018-06-05 17:00:00.0,2018-06-13 17:00:00.0]|[2018-06-09 10:17:37]                                          |[2]      |2            |
|2        |[2018-05-28 17:00:00.0,2018-06-05 17:00:00.0]|[2018-06-02 10:17:37, 2018-06-02 13:17:37]                     |[1, 2]   |1            |
|2        |[2018-06-05 17:00:00.0,2018-06-13 17:00:00.0]|[2018-06-08 14:19:37]                                          |[3]      |2            |
|2        |[2018-06-13 17:00:00.0,2018-06-21 17:00:00.0]|[2018-06-16 13:17:37, 2018-06-17 14:17:37]                     |[2, 3]   |3            |
+---------+---------------------------------------------+---------------------------------------------------------------+---------+-------------+
如果需要,可以分解存储ID或事务中的列表元素


希望有帮助

我没有使用提出的spark解决方案,而是使用纯sql逻辑和游标。这不是很有效,但我需要完成这项工作

要做您想要做的事情,您需要递归CTE。MySQL在v8+中支持这些功能。我不知道SparkSQL是否支持它们。@GordonLinoff知道如何编写它吗?我了解CTE概念,但不知道如何使用。在这种情况下