【问题标题】:Spark SQL - How to SUM values over date range linked to a especific dateSpark SQL - 如何对链接到特定日期的日期范围内的值求和
【发布时间】:2020-08-29 22:47:38
【问题描述】:

我需要对每个商店中的每种产品计算相对于该日期的过去 30 天(不包括在内)的值的总和。 假设所有月份都有 30 天:

date|store|product|values
2020-06-30|Store1|Product1|1
2020-07-02|Store1|Product2|4
2020-07-01|Store2|Product1|3
2020-07-18|Store1|Product1|4
2020-07-18|Store1|Product2|2
2020-07-18|Store2|Product1|2
2020-07-30|Store1|Product1|1
2020-08-01|Store1|Product1|1
2020-08-01|Store1|Product2|1
2020-08-01|Store2|Product1|6

在 2020-08-01 的行中,将 (2020-08-20 - 30 days) 的值与 2020-08-19 相加,并将其放入 2020-08-20 行,如下所示: (第一行不包括 '2020-06-30' 因为是 30 多天前和 '2020-08-01' 因为是同一天,这样继续......)

date|store|product|sum_values_over_last_30_days_to_this_date
2020-08-01|Store1|Product1|5
2020-08-01|Store1|Product2|6
2020-08-01|Store2|Product1|5
....

在下面尝试过,也没有:

spark.sql("""
SELECT 
a.date,
a.store,
a.product,
SUM(a.values) OVER (PARTITION BY a.product,a.store ORDER BY a.date BETWEEN a.date - INTERVAL '1' DAY AND a.date - INTERVAL '30' DAY) AS sum
FROM table a
""").show()

有人可以帮帮我吗?

【问题讨论】:

  • a.values 列在哪里?在你的桌子上?请正确给我们表格

标签: date apache-spark-sql sum date-range


【解决方案1】:

你可以试试self-join而不是窗口函数,也许这种join会起作用-

SELECT 
    a.date, 
    a.store,
    a.product,
    SUM(IFNULL(b.value,0))
FROM
    table a
LEFT JOIN
    (
        SELECT
            a.date, 
            a.store,
            a.product,
            a.value
        FROM
            table  a
    )b
ON
    a.store = b.store
AND
    a.product = b.product
AND
    a.date > b.date - INTERVAL 30 DAYS
AND a.date <= b.date
GROUP BY 
    1,2,3

确保对内部查询的值求和,直到今天为止。

【讨论】:

  • 谢谢@Assaf!!只是加入的日期我不得不修改为“AND(a.date - INTERVAL '30' DAY) b.date”并注意:必须每个日期、商店、产品(我的尺寸)一行。或者只是在加入之前按日期、商店、产品分组的 SUM 值。
【解决方案2】:

这是我对样本数据框的试用。

+----------+------+--------+------+
|      date| store| product|values|
+----------+------+--------+------+
|2020-08-10|Store1|Product1|     1|
|2020-08-11|Store1|Product1|     1|
|2020-08-12|Store1|Product1|     1|
|2020-08-13|Store1|Product2|     1|
|2020-08-14|Store1|Product2|     1|
|2020-08-15|Store1|Product2|     1|
|2020-08-16|Store1|Product1|     1|
|2020-08-17|Store1|Product1|     1|
|2020-08-18|Store1|Product1|     1|
|2020-08-19|Store1|Product2|     1|
|2020-08-20|Store1|Product2|     1|
|2020-08-21|Store1|Product2|     1|
|2020-08-22|Store1|Product1|     1|
|2020-08-21|Store1|Product1|     1|
|2020-08-22|Store1|Product1|     1|
|2020-08-20|Store1|Product2|     1|
|2020-08-21|Store1|Product2|     1|
|2020-08-22|Store1|Product2|     1|
+----------+------+--------+------+

df.withColumn("date", to_date($"date"))
  .createOrReplaceTempView("table")

spark.sql("""
    SELECT
        date,
        store,
        product,
        COALESCE(SUM(values) OVER (PARTITION BY 1 ORDER BY date RANGE BETWEEN 3 PRECEDING AND 1 PRECEDING), 0) as sum
    FROM table
""").show()

+----------+------+--------+---+
|      date| store| product|sum|
+----------+------+--------+---+
|2020-08-10|Store1|Product1|0.0|
|2020-08-11|Store1|Product1|1.0|
|2020-08-12|Store1|Product1|2.0|
|2020-08-13|Store1|Product2|3.0|
|2020-08-14|Store1|Product2|3.0|
|2020-08-15|Store1|Product2|3.0|
|2020-08-16|Store1|Product1|3.0|
|2020-08-17|Store1|Product1|3.0|
|2020-08-18|Store1|Product1|3.0|
|2020-08-19|Store1|Product2|3.0|
|2020-08-20|Store1|Product2|3.0|
|2020-08-20|Store1|Product2|3.0|
|2020-08-21|Store1|Product2|4.0|
|2020-08-21|Store1|Product1|4.0|
|2020-08-21|Store1|Product2|4.0|
|2020-08-22|Store1|Product1|6.0|
|2020-08-22|Store1|Product1|6.0|
|2020-08-22|Store1|Product2|6.0|
+----------+------+--------+---+

【讨论】:

    猜你喜欢
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多