我正在尝试编写SQL select查询来解决以下问题。我有一个客户列表,其帐户显示帐户开立日期和帐户关闭日期。我需要确定客户是否有资格根据他们是否在2014年9月30日之前拥有持续会员资格(即开设账户)进行投票。如果他们在开设新帐户的同一天关闭了帐户,则会计入持续会员资格。我的初始表如下:
CUS_ID | ACC_ID | OPEN_DT | CLOSE_DT
1 | 1001 | 01/01/2010 | 01/12/2013
1 | 1002 | 10/03/2014 | 01/11/2014
1 | 1003 | 01/11/2014 | 01/01/2015
1 | 1004 | 01/01/2015 | NULL
2 | 1005 | 01/01/2014 | 10/08/2014
2 | 1006 | 10/08/2014 | 01/02/2015
2 | 1007 | 05/02/2015 | NULL
3 | 1008 | 01/10/2014 | NULL
4 | 1009 | 01/09/2014 | 31/03/2015
您可以看到客户1自2014年3月10日起拥有持续会员资格,因此符合条件。 客户2没有资格,因为会员资格中断,他的最新帐户于2014年9月30日后开放。 客户3不符合资格,因为他的帐户于2014年9月30日后开立。由于帐户已关闭,客户4不符合资格。
我的结果应如下所示:
CUS_ID | ELIGIBLE
1 | Y
2 | N
3 | N
4 | N
我已尝试将表格与自己联系起来并使用关闭日期来处理开放日期,但在某些情况下,每个客户需要检查的记录超过2条。任何帮助将不胜感激。
答案 0 :(得分:0)
如果记录不重叠(与样本数据的情况一样),您可以使用一点技巧。计算自您感兴趣的日期以来的天数。然后将每个客户记录的记录天数相加。如果这些是平等的,那么所有日子都会被覆盖。
实现这一点需要一些逻辑,但这是一个想法:
select cus_id,
(case when sum(datediff(day,
(case when open_dt < thedate then thedate else open_dt end),
(case when close_dt > today or close_dt is null then today else close_dt end)
)) =
sum(datediff(day, thedate, today))
then 'y' else 'n'
end) as eligible
from table t cross join
(select cast('2014-09-30' as date) as thedate,
cast(getdate() as date) as today) as params
where close_dt is null or close_dt >= thedate
group by cus_id;
答案 1 :(得分:0)
递归CTE在这里是个不错的选择。
这是我的查询,但我没有进行测试,可能需要进行一些调试。
with a as
(
select CUS_ID , OPEN_DT
from tab as t1
where CLOSE_DT is null
UNION ALL
select cus_id, open_dt
from table1 as t2
inner join A as A1
on A1.CUS_ID = T2.Cust_ID AND A1.Open_dt = t2.close_dt
)
Select Cust_id, Eligible case when MIN(open_dt) < '2014-09-30' then 'Y' else 'N' from a group by Cust_id