使用 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;
问题
这是我询问的
我有一个 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;