Pyspark - последняя запись пользователя и подведение итогов - PullRequest
1 голос
/ 21 февраля 2020

Можете ли вы придумать более простой способ достижения этого результата?

В этом случае я суммирую результаты для каждого идентификатора. Идея состоит в том, чтобы привести последнее значение и общее количество на пользователя.

Большое спасибо!

tmp= spark.createDataFrame(
    [
        (1, '2020-02-17',10), 
        (1, '2020-02-16',14),
        (1, '2020-02-15',19),
        (2, '2020-02-17',15),
        (2, '2020-02-19',9),
    ],
    ['id','date','value'] 
)

tmp.createOrReplaceTempView('tmp_sql')

ver_sum = spark.sql("""
                SELECT id, 
                       value                       
                FROM tmp_sql as t
                WHERE NOT EXISTS (
                  SELECT *
                  FROM tmp_sql AS witness
                  WHERE witness.id = t.id AND witness.date > t.date
                )
""")

ver_sum.createOrReplaceTempView('ver_sum_sql')


spark.sql(""" select a.id,
                     a.value as last_value,
                     sum(b.value) as tot_value

              from ver_sum_sql a
                  join tmp_sql b on a.id = b.id
              group by 1,2
         """).show()

+---+----------+---------+
| id|last_value|tot_value|
+---+----------+---------+
|  1|        10|       43|
|  2|         9|       24|
+---+----------+---------+

1 Ответ

1 голос
/ 21 февраля 2020

Если вам часто нужна эта информация в актуальном состоянии, вы можете создать таблицу с этими столбцами (то есть id, last_value, tot_value) и обновить эту таблицу с помощью триггера для исходной таблицы.

Если вы хотите продолжайте работу над запросами, затем рассмотрите возможность изменения SELECT * на SELECT 1 для первого запроса, чтобы повысить производительность, поскольку этот подзапрос предназначен только для фильтрации, а не для выбора всех столбцов (хотя хороший оптимизатор оптимизировал бы его автоматически, но измените его на всякий случай).

Я не уверен насчет производительности следующего совета, но во втором запросе вы можете сначала найти сумму значений, а затем объединить результаты (в противном случае результат объединение - это большие временные данные), поэтому вы можете попробовать

select lastv.id    as id,
       lastv.value as last_value,
       sumv.sum    as tot_value
from ver_sum_sql as lastv
join (
    select id, sum(value) as sum
    from tmp_sql
    group by id
) as sumv
on lastv.id = sumv.id

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...