微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过年份,Oracle SQL

如何解决通过年份,Oracle SQL

我正在尝试创建一个查询,该查询对一年内存在的记录进行计数。该表如下所示:

Title_ID   ISSUE_DATE   EXPIRY_DATE   CLIENT_NUMBER
123        '26-JUN-19'  '17-AUG-20'   8529
124        '04-APR-19'  '17-SEP-22'   8529
125        '09-MAY-15'  '11-SEP-19'   3654
126        '31-DEC-19'  '25-NOV-22'   9852
127        '27-OCT-18'  '26-FEB-21'   2254
128        '05-OCT-11'  '01-JAN-19'   9852

具体地说,我想计算给定日历年中存在的不同CLIENT_NUMBERS条记录。

记录(标题)从ISSUE_DATE到EXPIRY_DATE一直存在。如果该记录在一年中的某个时间点存在(比如说2019年),那么我们有兴趣将其包括在客户数量中。

因此,如果记录在2019年发布,或者如果记录在2019年过期,如果记录在2019年之前发布且在2019年之后过期,那么我们很感兴趣将其计入其存在的年份的客户计数中。

我建立了以下查询来执行此操作,但仅针对特定的一年(2019年)。我想进一步构建查询,以便在客户拥有有效标题时查看每个日历年并计算不同的客户编号:

SELECT *
--  count(distinct client_number)
FROM
  TITLE
WHERE
  issue_date between '01-Jan-19' and '31-Dec-19'
  or expiry_date between '01-Jan-19' and '31-Dec-19'
  or (issue_date < '01-Jan-19' and expiry_date > '31-Dec-19')

我遇到麻烦的地方,我的数据比我提供的子集大得多。我想使用相同的逻辑,按年递归地获得不同客户数量的计数,以包括我上面概述的日历年内的记录。所以,我想要一张这样的桌子:

YEAR    COUNT_OF_CLIENT_NUMBERS
2020    5469
2019    5587
2018    4852
2017    4501
2016    3265
etc

我认为目前我已经对当前的sql功能感到困惑,所以我想问一下是否有任何建议可以实现这一目标?

谢谢。

编辑:为澄清起见,发布日期和有效期适用于标题,而不适用于客户。因此,标题在发布日期发布,并在到期日期过期。客户可以拥有一个或多个标题

因此,我希望统计一个特定年度内,如果一个或多个客户处于活跃状态,那么有多少不同的客户拥有该年度的活跃标题。因此,关键是,如果一个标题是在该年份 OR 发布的,并且在该年之前发布的,而在该年份之前发布的,并且在该年之后过期的,则该标题被认为是有效的。标题可以可以使用多年(例如,于2014年2月4日发布,于2017年4月7日到期),我想列出存在该标题的每一年的客户数量.... 2014 ,2015、2016和2017年)。

因此,我创建了一个要联接的表(感谢@GMB的建议):

with calendar_year (y) as 
  (
  select 2010 from dual
  union all select y + 1 from calendar_year where y < 2020
  )
  
select * from calendar_year

哪个返回:

2010
2011
2012
2013
2014
etc

我想将其加入到标题表中,但是在递归查看发布日期和有效期以将标题合并到其存在的年限时,我遇到了一些问题。在该领域的任何帮助都将非常棒! / p>

解决方法

通过取消数据透视表,您可以在任何一天获得客户数量,因此每个日期只有一行。然后跟踪“进”和“出”。

您没有指定数据库,但这是一种方法:

select dte,sum(inc),sum(sum(inc)) over (order by dte) as active_on_date
from ((select issue_date as dte,1 as inc
       from t
      ) union all
      (select expiry_date as dte,-1 as inc
       from t
      ) 
     ) t
group by dte
order by dte;

编辑:

嗯,以上内容可能无法完全满足您的要求。如果您要计算与众不同的客户编号而不是总行数,则只列出日期和join可能会更简单:

select d.dte,count(distinct t.client_id)
from (select date '2020-01-01' as dte from dual union all
      select date '2019-01-01' as dte from dual union all
      select date '2018-01-01' as dte from dual union all
      . . .
     ) d left join
     t
     on d.dte between t.issue_dte and t.expiry_dte
group by d.dte
order by d.dte;
,

您可以使用递归查询生成年份,然后通过左连接将表带进去并进行汇总:

with dates (dt) as (
    select date '2016-01-01' from dual
    union all select add_months(dt,1) from dates where dt < date '2020-01-01'
)
select d.dt,count(distinct t.client_number) count_of_client_numbers
from dates d
left join title t 
    on t.issue_date <= d.dt
    and t.expiry_date > d.dt
group by d.dt

这种方法的好处是,您可以获得每年的结果,甚至没有标题开始或结束的地方。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。