在使用Union时如何模仿ON条件?

问题描述

我有这样的查询

select
    yyyy_mm_dd,xml_id,feature,status
from
    schema.t1
where
    yyyy_mm_dd >= '2019-02-02'

union all

select
    yyyy_mm_dd,p_id as xml_id,'payment' as feature,case
        when payment = 1 then 1
        else 0
    end as status
from
    schema.t2
where
    yyyy_mm_dd >= '2019-02-02'

有没有一种方法可以确保union的任一边都不比另一边有更大的日期?通过联接,我可以在on上使用yyyy_mm_dd条件来强制执行此操作。我想维护联合,但只保留到两个表中可用的最大日期。


是否有比我想出的解决方案更有效的解决方法

select
    c.yyyy_mm_dd,status
from
    schema.t1 c
left join(
    select
        max(yyyy_mm_dd) as yyyy_mm_dd
    from
        schema.t2
    where
        yyyy_mm_dd >= '2020-10-01'
) m on m.yyyy_mm_dd = c.yyyy_mm_dd
where
    c.yyyy_mm_dd >= '2020-10-01'
    and m.yyyy_mm_dd is null
    
union all

select
    c.yyyy_mm_dd,case
        when payment = 1 then 1
        else 0
    end as status
from
    schema.t2 c
left join(
    select
        max(yyyy_mm_dd) as yyyy_mm_dd
    from
        schema.t1
    where
        yyyy_mm_dd >= '2020-10-01'
) m on m.yyyy_mm_dd = c.yyyy_mm_dd

where
    c.yyyy_mm_dd >= '2020-10-01'
    and m.yyyy_mm_dd is not null

解决方法

为每个查询创建2个CTE,然后仅选择每个CTE在其他CTE中具有匹配的yyyy_mm_dd的行:

with 
  cte1 as (
    select yyyy_mm_dd,xml_id,feature,status
    from schema.t1
    where yyyy_mm_dd >= '2019-02-02'
  ),cte2 as (
    select yyyy_mm_dd,p_id as xml_id,'payment' as feature,case when payment = 1 then 1 else 0 end as status
    from schema.t2
    where yyyy_mm_dd >= '2019-02-02'
  )
select c1.* from cte1 c1
where exists (select 1 from cte2 c2 where c2.yyyy_mm_dd = c1.yyyy_mm_dd)
union all
select c2.* from cte2 c2
where exists (select 1 from cte1 c1 where c1.yyyy_mm_dd = c2.yyyy_mm_dd)