Как объединить таблицу со столбцами 'valid_from' и 'valid_to' в таблицу с отметкой времени? - PullRequest
0 голосов
/ 18 мая 2018

Я работаю в PySpark и у меня есть таблица, которая содержит данные о продажах для конкретных товаров, с одной строкой на дату и товар:

#ARTICLES
+-----------+----------+
|timestamp  |article_id|
+-----------+----------+
| 2018-01-02|   1111111|
| 2018-01-02|   2222222|
| 2018-01-02|   3333333|
| 2018-01-03|   1111111|
| 2018-01-03|   2222222|
| 2018-01-03|   3333333|
+-----------+----------+

Затем у меня есть таблица меньшего размера, которая содержит данные о ценах для каждого товара.статья.Цены действительны от некоторой даты до другой даты, которая указана в двух последних столбцах:

#PRICES
+----------+-----+----------+----------+
|article_id|price|from_date |to_date   |
+----------+-----+----------+----------+
|   1111111| 8.99|2000-01-01|2999-12-31|
|   2222222| 4.29|2000-01-01|2006-09-05|
|   2222222| 2.29|2006-09-06|2999-12-31|
+----------+-----+----------+----------+

В последних двух строках вы видите, что эта цена была снижена в 2006-09-06.

Теперь я хотел бы присоединить цену к первому столу.Это должна быть цена на соответствующей метке времени.В этом примере я хотел бы получить следующий результат:

#RESULT
+-----------+----------+-----+
|timestamp  |article_id|price|
+-----------+----------+-----+
| 2018-01-02|   1111111| 8.99|
| 2018-01-02|   2222222| 2.29|
| 2018-01-02|   3333333| null|
| 2018-01-03|   1111111| 8.99|
| 2018-01-03|   2222222| 2.29|
| 2018-01-03|   3333333| null|
+-----------+----------+-----+

Как мне лучше всего это сделать?

Одна из моих идей заключалась в том, чтобы «развернуть» таблицу цен, чтобы она содержала одинстрока на отметку времени и article_id, а затем объединить с помощью этих двух ключей.Но я не знаю, как развернуть таблицу, используя два столбца даты.

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Другой вариант - сделать левое соединение и использовать pyspark.sql.functions.where(), чтобы выбрать price.

import pyspark.sql.functions as f
articles.alias("a").join(prices.alias("p"), on="article_id", how="left")\
    .where(
        f.col("p.article_id").isNull() |  # without this, it becomes an inner join
        f.col("timestamp").between(
            f.col("from_date"),
            f.col("to_date")
        )
    )\
    .select(
        "timestamp",
        "article_id",
        "price"
    )\
    .show()
#+----------+----------+-----+
#| timestamp|article_id|price|
#+----------+----------+-----+
#|2018-01-02|   1111111| 8.99|
#|2018-01-02|   2222222| 2.29|
#|2018-01-02|   3333333| null|
#|2018-01-03|   1111111| 8.99|
#|2018-01-03|   2222222| 2.29|
#|2018-01-03|   3333333| null|
#+----------+----------+-----+
0 голосов
/ 18 мая 2018

Это еще один способ достижения желаемого результата

from pyspark.sql import functions as f
result = articles.alias('articles').join(prices.alias('prices'), (f.col('articles.article_id') == f.col('prices.article_id')) & (f.col('articles.timestamp') > f.col('prices.from_date')) & (f.col('articles.timestamp') < f.col('prices.to_date')), 'left')\
    .select('articles.*','prices.price')

result должно быть

+----------+----------+-----+
|timestamp |article_id|price|
+----------+----------+-----+
|2018-01-02|2222222   |2.29 |
|2018-01-03|2222222   |2.29 |
|2018-01-02|3333333   |null |
|2018-01-03|3333333   |null |
|2018-01-02|1111111   |8.99 |
|2018-01-03|1111111   |8.99 |
+----------+----------+-----+
0 голосов
/ 18 мая 2018

Соединение между условиями должно работать.

from pyspark.sql.functions import col
articles.alias('articles').join(prices.alias('prices'), 
   on=(
        (col('articles.article_id') == col('prices.article_id')) & 
        (col('articles.timestamp').between(col('prices.from_date'), col('prices.to_date')))
   ),
   how='left'
).select('articles.*','prices.price')
...