使用 OVER 的自定义聚合函数,同时回退到默认值

custom aggregation function using OVER while falling back to a default value

问题

这是我询问的 的跟进。但是那个有点太笼统了。现在,我关注的是新的、更具体的问题。

我有一个 table 个帐户:

acct_num | ssn       | branch | open_date    |close_date  | 
----------------------------------------------------------| 
0123456  | 123456789 | 01     | 01/01/2000   | NULL       | 
0123457  | 123456789 | 02     | 03/05/2004   | NULL       | 
1234405  | 322145678 | 04     | 04/16/2016   | 05/01/2016 |   

注意 ssn 123456789 如何有两个帐户。

我想创建一个数据集,用名为 mbr_open_date 的列扩充此 table 中的每一行。

如果一个 ssn 有一个开放的帐户,那么 mbr_open_date 应该是最早 open_date 和非空 close_date 帐户上的 open_date

如果 ssn 没有开放帐户,那么 mbr_open_date 应该回退到最小值 open_date

所以我期望从上面的例子中得到的结果集是:

acct_num | ssn       | branch | open_date    |close_date  | mbr_open_date | 
--------------------------------------------------------------------------|  
0123456  | 123456789 | 01     | 01/01/2000   | NULL       | 01/01/2000    | 
0123457  | 123456789 | 02     | 03/05/2004   | NULL       | 01/01/2000    | 
1234405  | 322145678 | 04     | 04/16/2016   | 05/01/2016 | 04/16/2016    | 

尝试过的解决方案

我首先尝试的是:

SELECT

  *
  , (
    SELECT MAX(ssn_open)
    FROM (VALUES
      (MIN(CASE WHEN is_open = 1 THEN open_date END) OVER (PARTITION BY ssn)),
      (MIN(open_date) OVER (PARTITION BY ssn))
    ) as candidates(ssn_open)
  ) mbr_open_date

FROM Account

这会产生以下错误:

Windowed functions can only appear in the SELECT or ORDER BY clauses.

所以,然后我尝试了这个:

SELECT

  *
  , CASE WHEN
    ((MIN(CASE WHEN is_open = 1 THEN open_date END) OVER (PARTITION BY ssn)) as ssn_open) IS NULL
    THEN ssn_open ELSE (MIN(open_date) OVER (PARTITION BY ssn))
  END mbr_open_date

FROM Account

这会产生以下错误:

Incorrect syntax near the keyword 'as'.

现在,我没主意了。

谁能帮帮我?

为什么需要子查询?我认为 COALESCE() 捕获了您想要的逻辑:

SELECT . . .,
       COALESCE(MIN(CASE WHEN is_open = 1 THEN open_date END) OVER (PARTITION BY ssn),
                MIN(open_date) OVER (PARTITION BY ssn)
               ) as mbr_open_date
FROM Account;