【问题标题】:creating multiple custom aggregation functions创建多个自定义聚合函数
【发布时间】:2016-06-04 01:02:41
【问题描述】:

我有一张名为 Account 的表。

此表的简化视图如下:

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

注意 ssn 123456789 有 2 个帐户。

我需要创建一个新数据集,该数据集按acct_num 对表进行分组,并显示基于每个组中的行计算的新列。

不过,这些计算本质上是多种多样的。

我需要的表格(在这个简化的例子中)如下:

ssn       |  home_branch    | date_of_first_membership   |   eligibility_indicator
-----------------------------------------------------------------------------------

显然ssn 很容易,但目前其他的都超出了我的范围。

  • home branchbranch 的值,来自最早的 open_date 和非空 close_date 的行。

  • open_date只是组中open_date的最小值。

  • eligibility_status 为 1,如果至少 1 个开户 has_product1 和至少 1 个(可能不同)开户 has_product2

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

ssn       | home_branch     | date_of_first_membership   | eligibility_indicator
-----------------------------------------------------------------------------------
123456789 | 01              | 01/01/2000                 | 1
322145678 | 04              | 04/16/2016                 | 0

编辑:

cmets 指出了一个矛盾。为了解决这个矛盾,我现在想过滤掉所有没有开户的ssn。

所以,新的预期结果集是:

ssn       | home_branch     | date_of_first_membership   | eligibility_indicator
-----------------------------------------------------------------------------------
123456789 | 01              | 01/01/2000                 | 1

【问题讨论】:

  • 看起来很简单。你试过什么?
  • 您的预期结果与此语句相矛盾(主分支是具有最早 open_date 和非空 close_date 的行中的分支的值。)
  • 对不起,你是对的。我要编辑这个问题。我想过滤掉没有任何未结账户的 SSN。

标签: sql tsql group-by aggregate-functions


【解决方案1】:

您可以使用条件聚合来做到这一点。第一个计算需要一点技巧——获取没有结束日期的行的最短日期:

select ssn,
       max(case when open_date = min_open_date then branch end) as home_branch,
       min(open_date) as date_of_first_membership,
       (case when max(has_product1) > 0 and max(has_product2) > 0
             then 1 else 0
        end) as eligibility_indicator
from (select a.*,
             min(case when close_date is null then open_date end)  over (partition by ssn ) as min_opendate
      from account a
     ) a
group by ssn;

【讨论】:

  • 所以min_open_date 是您添加到末尾的那个新列的值吗?你能解释一下over (partition by ssn) 位的作用吗?
【解决方案2】:

在 2008 年的 sql server 中测试

create table account (
    acct_num varchar(15), 
    ssn int, 
    branch varchar(10), 
    open_date Date, 
    close_date Date, 
    has_product1 int, 
    has_product2 int, 
)
insert into account
values (0123456,123456789,01,'01/01/2000',null, 1,0),
(0123457,123456789,02,'03/05/2004',null, 0,1),
(1234405,322145678 ,04,'04/16/2016','05/01/2016', 1,1)


select *, (select branch from account where open_date = x.date_of_first_membership and ssn = x.ssn) home_branch from (
select ssn, MIN(open_date) date_of_first_membership,
case when close_date is not null then 0 ELSE
case when MAX(has_product1) > 0 and MAX(has_product2) >0 then 1 ELSE 0 end end eligibility_indicator
  from account
  where close_date is null
   group by ssn, close_date
  ) x

【讨论】:

    猜你喜欢
    • 2018-10-15
    • 2019-03-25
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2021-06-04
    • 2022-01-12
    • 1970-01-01
    • 2019-11-05
    相关资源
    最近更新 更多