问题描述
where yyyy_mm_dd >= '2019-02-01'
and yyyy_mm_dd <= second highest date in a table
为此,我使用了以下代码:
where
p.yyyy_mm_dd >= "2019-02-02"
and p.yyyy_mm_dd <= (select max(yyyy_mm_dd) from schema.table1 where yyyy_mm_dd < (select max(yyyy_mm_dd) from schema.table1 where yyyy_mm_dd is not null))
上面的代码用spark.sql()
包裹时有效,但是当我运行不带Spark的查询(即作为原始HQL)时,遇到了此错误:
编译语句时出错:失败:ParseException行102:25无法识别表达式规范中'select''max''('附近的输入
where
p.yyyy_mm_dd >= "2019-02-02"
and p.yyyy_mm_dd <= (select max(t1.yyyy_mm_dd) from schema.table1 t1 where t1.yyyy_mm_dd < (select max(t2.yyyy_mm_dd) from schema.table2 t2 where t2.yyyy_mm_dd is not null))
尽管如此,我仍然遇到相同的错误。
表1:
| yyyy_mm_dd | company_id | account_manager |
|------------|------------|-----------------|
| 2020-11-10 | 321 | Peter |
| 2020-11-09 | 632 | John |
| 2020-11-08 | 598 | Doe |
| 2020-11-07 | 104 | Bob |
| ... | ... | ... |
| ... | ... | ... |
表2:
| yyyy_mm_dd | company_id | tier |
|-------------------|------------|--------|
| 2020-11-10 | 321 | bronze |
| 2020-11-09 | 632 | Silver |
| 2020-11-08 | 598 | Gold |
| 2020-11-07 | 104 | Bob |
| ... | ... | ... |
| ... | ... | ... |
| 2019_12_13_backup | 321 | bronze |
| 2019_12_13_backup | 632 | Silver |
| ... | | |
查询:
select
p.yyyy_mm_dd,p.company_id,p.account_manager,t.tier
from
table1 p
left join(
select
yyyy_mm_dd,company_id,max(tier) as tier
from
table2
where
yyyy_mm_dd >= "2019-02-02"
group by
1,2
) t on (t.company_id = p.company_id and t.yyyy_mm_dd = p.yyyy_mm_dd)
where
p.yyyy_mm_dd >= "2019-02-02"
and p.yyyy_mm_dd <= (select max(yyyy_mm_dd) from table2 where yyyy_mm_dd < (select max(yyyy_mm_dd) from table2 where yyyy_mm_dd is not null))
由于table2
在backup_2019_12_31
列中包含yyyy_mm_dd
,因此在表上执行max()
时将返回这些行。因此,我需要获取第二高的值,该值将从此处的数据集中为2020-11-10
。每个company_ids
有多个yyyy_mm_dd
。
本质上,我想查询table1
,其中yyyy_mm_dd
在table1
起点(硬编码为2019-02-02
)和table2
的真实最大日期之间
解决方法
要从table3中获取第二高的日期,可以使用density_rank。日期第二高的所有行将被分配rn = 2。使用LIMIT获得单行,或者使用max()或同一行的不同聚合,然后使用max_date和filter交叉连接表。
with max_date as(
select yyyy_mm_dd
from
(
select yyyy_mm_dd,dense_rank() over(order by yyyy_mm_dd desc) rn
from table2
)s
where rn=2 --second max date
limit 1 --need only one record
)
select t1.*
from table1 t1
cross join max_date t2
where t1.yyyy_mm_dd <= t2.yyyy_mm_dd