所以我有这个查询,它给出了在给定时间范围内每个月至少进行一次某种交易的账户数。在这种情况下,我会检查3个月内的交易。请参阅以下查询:
select
Yr
, count(distinct acct_nbr) as AcctCt
from (
select
Yr
, acct_nbr
, count(distinct Mth) as Mths
from (
select
extract(year from tran_dt) as Yr
, acct_nbr
, extract(month from tran_dt) as Mth
, tran_id
from br.bdft
where prod_type = 44
and (tran_dt between '2017-10-01' and '2017-12-31'
or tran_dt between '2016-10-01' and '2016-12-31'
or tran_dt between '2015-10-01' and '2015-12-31'
or tran_dt between '2014-10-01' and '2014-12-31'
or tran_dt between '2013-10-01' and '2013-12-31')
and tran_cd = 'DD'
) dt
group by 1,2
) dt2
where Mths = 3
group by 1
我得到的结果如下:
Yr: AcctCt:
2017 258527
2016 231304
2015 188550
2014 210339
2013 170781
我目前按年度对结果进行分组,方法是从交易日期中提取年份。当日期范围跨越多年时(例如我在上面的查询中使用的内容),这样可以正常工作。但是,一旦我跨越了多年,例如2017-11-01至2018-01-31,这种方法不再有效。
是否有更好的方法可以将结果分组,无论我使用的日期范围如何,它总是有效?
答案 0 :(得分:2)
创建第二个表以保存时间段(重度伪代码:将表time_periods创建为ID,period_name,start_date,end_date)。加入此表
new T[C]
按period_name列分组。
抱歉,时间紧迫,或者我会提供更多信息......但是概念就在这里(在表中定义时间段并使用之间连接到该表)。尝试一下,如果您仍然需要
,我会在今天/明天再次访问完整的解决方案答案 1 :(得分:1)
当他们跨越多年时,只需减去一定的时间。对于您的示例,请将此表达式用于Yr
:
extract(year from add_months(tran_dt, -1) ) as Yr
答案 2 :(得分:1)
在提取年份之前,只需使用ADD_MONTHS调整日期即可。此外,不需要两个COUNT(DISTINCT)。
这是您简化的查询:
select
Yr
, count(*) as AcctCt
from (
select
Extract(YEAR From Add_Months(tran_dt,-1)) as Yr
, acct_nbr
from br.bdft
where prod_type = 44
and (tran_dt between '2017-11-01' and '2018-01-31'
or tran_dt between '2016-11-01' and '2017-01-31'
or tran_dt between '2015-11-01' and '2016-01-31'
or tran_dt between '2014-11-01' and '2015-01-31'
or tran_dt between '2013-11-01' and '2014-01-31')
and tran_cd = 'DD'
group by acct_nbr
, yr
having count(distinct extract(month from tran_dt)) = 3
) dt
group by 1
编辑:
要获得基于今天的三个月范围,您可以在CURRENT_DATE应用TRUNC / LAST_DAY / ADD_MONTHS计算。
select
Yr
, count(*) as AcctCt
from (
select
-- shift back the date between 0 and 2 months based on the month of the current quarter
-- to get the same year for consecutive months
Extract(YEAR From Add_Months(tran_dt, -Extract(MONTH From currdt) MOD 3)) as Yr
, acct_nbr
from br.bdft
where prod_type = 44
-- get the current months plus the two previous for the current and the previous four years
-- will be calculated once = Explain shows hard-coded dates
AND ( tran_dt BETWEEN Trunc(Add_Months(Current_Date,-2 ), 'mon') AND Last_Day( Current_Date )
OR tran_dt BETWEEN Trunc(Add_Months(Current_Date,-2 -1*12), 'mon') AND Last_Day(Add_Months(Current_Date,-1*12))
OR tran_dt BETWEEN Trunc(Add_Months(Current_Date,-2 -2*12), 'mon') AND Last_Day(Add_Months(Current_Date,-2*12))
OR tran_dt BETWEEN Trunc(Add_Months(Current_Date,-2 -3*12), 'mon') AND Last_Day(Add_Months(Current_Date,-3*12))
OR tran_dt BETWEEN Trunc(Add_Months(Current_Date,-2 -4*12), 'mon') AND Last_Day(Add_Months(Current_Date,-4*12))
)
and tran_cd = 'DD'
group by acct_nbr
, yr
having count(distinct extract(month from tran_dt)) = 3
) dt
group by 1 as Yr