Apache spark 如何将具有“valid_from”和“valid_to”列的表连接到具有时间戳的表?

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

我在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|
+-----------+----------+-----+
我最好怎么做

我的一个想法是推出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的行。已更新!我错过了那个条件。它实际上应该是左连接,而不是内部连接。