首页 > 解决方案 > 在连接的 ON 子句中使用 case

问题描述

我有一个问题:在 JOIN 的 ON 子句中使用 CASE 语句的正确方法是什么?(我看到其他人提出了几个类似的问题,但我不知道如何在我的场景中复制解决方案。)

我尝试连接同一张表的 2 个实例(自连接)。该表包含每个客户每天的余额值(每个客户每天的行,每个客户出现多次 - 从他活动的第一天到他/她关闭帐户)

在此处输入图像描述

对于每个客户,我需要在另一列中找到今天的余额是多少 - “基准日期”的余额是多少。基准日期的默认值为 2019 年 12 月 31 日,如果客户来自特定分支机构 (BRANCH "X"),则基准日期应为 2020 年 3 月 31 日(而不是 2019 年 12 月 31 日)。所以我想做的是写这样的东西:

select 
B.branch_name,
B.customer_id,
B.balance as current_balance,
B1.balance as base_date_balance,
from 
balance B inner join balance B1
on B.customer_id=B1.customer_id
and B.date = '20apr2020'
and B1.date= (case when B.branch_name = 'X' then '31-mar-2020' else '31-dec-2019' end)

我知道这不是正确的方法,但我无法弄清楚正确的方法是什么。提前感谢所有答案和帮助,非常感谢!:)

标签: sqlself-join

解决方案


使用窗口函数!:

select b.*,
       max(case when branch = 'B' and date = date '2019-03-31' then balance
                when date = date '2019-12-31' then balance
           end) over (partition by customer_id, branch_name
                     ) as base_date_balance
from balance b;

这应该比JOINwith an ORorCASE条件具有更好的性能。

或者,join看起来像:

from b join
     b bbase
     on bbase.customer_id = b.customer_id and
        bbase.branch_name = b.branch_name and
        ( (bbase.branch_name = 'B' and bbase.date = date '2019-03-31') or
          (bbase.branch_name <> 'B' and bbase.date = date '2019-12-31')
        )

推荐阅读