Apache spark 如何将具有“valid_from”和“valid_to”列的表连接到具有时间戳的表?
我在PySpark工作,有一个表,其中包含特定文章的销售数据,每个日期和文章一行:Apache spark 如何将具有“valid_from”和“valid_to”列的表连接到具有时间戳的表?,apache-spark,pyspark,apache-spark-sql,pyspark-sql,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Sql,我在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
#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|
+-----------+----------+-----+
我最好怎么做
我的一个想法是推出price表,每个时间戳和article_id包含一行,然后使用这两个键进行连接。但我不知道如何使用这两个日期列展开表格。
连接与中间条件应起作用
从pyspark.sql.functions导入col
articles.alias'articles.joinprices.alias'prices',
在=
col'articles.article_id'==col'prices.article_id'&
col'articles.timestamp.在col'prices.from_date'和col'prices.to_date'之间
,
怎么走
.选择'articles.'、'prices.price'
连接与中间条件应起作用
从pyspark.sql.functions导入col
articles.alias'articles.joinprices.alias'prices',
在=
col'articles.article_id'==col'prices.article_id'&
col'articles.timestamp.在col'prices.from_date'和col'prices.to_date'之间
,
怎么走
.选择'articles.'、'prices.price'
另一个选择是做一个左连接并使用来选择价格 导入pyspark.sql.f函数 articles.aliasa.joinprices.aliasp,on=article\u id,how=left\ 哪里 f、 colp.article_id.isNull |如果没有这个,它将成为一个内部连接 f、 coltimestamp.between f、 从科卢日起, f、 科尔托日 \ 选择 时间戳, 第11条, 价格 \ 显示 +-----+-----+---+ |时间戳|商品id |价格| +-----+-----+---+ |2018-01-02| 1111111| 8.99| |2018-01-02| 2222222| 2.29| |2018-01-02 | 3333333 |空| |2018-01-03| 1111111| 8.99| |2018-01-03| 2222222| 2.29| |2018-01-03 | 3333333 |空| +-----+-----+---+
另一个选择是做一个左连接并使用来选择价格 导入pyspark.sql.f函数 articles.aliasa.joinprices.aliasp,on=article\u id,how=left\ 哪里 f、 colp.article_id.isNull |如果没有这个,它将成为一个内部连接 f、 coltimestamp.between f、 从科卢日起, f、 科尔托日 \ 选择 时间戳, 第11条, 价格 \ 显示 +-----+-----+---+ |时间戳|商品id |价格| +-----+-----+---+ |2018-01-02| 1111111| 8.99| |2018-01-02| 2222222| 2.29| |2018-01-02 | 3333333 |空| |2018-01-03| 1111111| 8.99| |2018-01-03| 2222222| 2.29| |2018-01-03 | 3333333 |空| +-----+-----+---+
这是实现您期望结果的另一种方式
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')
这是实现您期望结果的另一种方式
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')
我认为这应该有效,但我没有得到正确的结果。另外,double&是一个语法错误。将其更改为单个&将导致空数据帧。我使用的spark版本2.1可能有问题。将prices.from_date和prices.to_date之间的col包装几乎可以给出正确的结果,但它不包括price为null的行。已更新!我错过了那个条件。它实际上应该是左连接,但不是内部连接。我认为这应该有效,但我没有得到正确的结果。另外,double&是一个语法错误。将其更改为单个&将导致空数据帧。我使用的spark版本2.1可能有问题。将prices.from_date和prices.to_date之间的col包装几乎可以给出正确的结果,但它不包括price为null的行。已更新!我错过了那个条件。它实际上应该是左连接,而不是内部连接。