如何在where子句中引用来自另一个cte的日期范围而不加入它?

tyu7yeag  于 2021-06-24  发布在  Hive
关注(0)|答案(1)|浏览(257)

我正在尝试为hive编写一个查询,它使用系统日期来确定昨天的日期和30天前的日期。这将为我提供30天的滚动时间,而无需每次运行查询时手动将日期范围提供给查询。
我的代码在cte中运行良好。我遇到的问题是在另一个cte中引用这些日期而不将cte连接在一起,这是我无法做到的,因为没有一个公共字段可以连接。
我尝试过各种方法,但每次都会得到一个“parseexception”。

WITH
date_range AS (
SELECT
CAST(from_unixtime(unix_timestamp()-30*60*60*24,'yyyyMMdd') AS INT) AS start_date,
CAST(from_unixtime(unix_timestamp()-1*60*60*24,'yyyyMMdd') AS INT) AS end_date
)
SELECT * FROM myTable
WHERE date_id BETWEEN (SELECT start_date FROM date_range) AND (SELECT end_date FROM date_range)

预期结果是mytable中的一组记录,这些记录的日期id介于cte date范围中的开始日期和结束日期之间。也许我把这一切都搞错了?

pbossiut

pbossiut1#

你可以做交叉连接,它不需要条件。您的日期范围数据集仅为一行,如有必要,您可以将其与\u表交叉联接,并将其转换为Map联接(您的小数据集将广播到所有Map器并加载到每个Map器内存中,运行速度将非常快),请检查 EXPLAIN 命令并确保它是Map联接:

set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.filesize=250000000;

WITH
date_range AS (
SELECT
CAST(from_unixtime(unix_timestamp()-30*60*60*24,'yyyyMMdd') AS INT) AS start_date,
CAST(from_unixtime(unix_timestamp()-1*60*60*24,'yyyyMMdd') AS INT) AS end_date
)

SELECT t.* 
  FROM myTable t
CROSS JOIN date_range d
WHERE t.date_id BETWEEN d.start_date AND d.end_date

如果您可以在where子句中计算日期:

SELECT t.* 
  FROM myTable t
CROSS JOIN date_range d
WHERE t.date_id 
      BETWEEN CAST(from_unixtime(unix_timestamp()-30*60*60*24,'yyyyMMdd') AS INT) 
          AND CAST(from_unixtime(unix_timestamp()-1*60*60*24,'yyyyMMdd') AS INT)

相关问题