Trying to develop a query in SQL which finds the time frame between two dates with added criteria

Ok  I want to find the number of days between a cancellation and purchase without including repeat cancellations...

So if new customer then initial value for purchase history = A
If they looked at data put it in cart and no purchase = B
Purchase = C

So I want to get the following data from a pattern

new customer       A
1-Jan-14                     C
2-Jan-14                     B
3-Jan-14                     C
4-Jan-14                 C
5-Jan-14                     B
6-Jan-14                     C
7-Jan-14                     B
8-Jan-14                     B
9-Jan-14                     B
10-Jan-14                     C

So I would like to know the results of days between every instance of B if it follows a C or A. Without getting results for any B which follows a B.

IE the January 7 B had a C appointment three days later.
I would get no results from the Jan 8 or 9th B.
LVL 9
Sean MeyerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

PortletPaulfreelancerCommented:
are you using SQL Server 2012 or later? (the LEAD() function might help solve this)
0
PortletPaulfreelancerCommented:
Here is an approach using a CTE and a self-join. I have included a third column (clientID) as I presume something like that will be present and will be needed.

Here's my result, note the "dayz" is calculated as a duration, it may be 1 day more than you want (that can be fixed):
| RN |   C2RN | ACODE | C2CODE |      ADATE |     C2DATE |   DAYZ |
|----|--------|-------|--------|------------|------------|--------|
|  1 |      2 |     A |      C | 2014-01-01 | 2014-01-01 |      1 |
|  2 |      3 |     C |      C | 2014-01-01 | 2014-01-01 |      1 |
|  3 |      4 |     C |      B | 2014-01-01 | 2014-01-02 |      2 |
|  5 |      6 |     B |      C | 2014-01-02 | 2014-01-03 |      2 |
|  6 |      7 |     C |      C | 2014-01-03 | 2014-01-03 |      1 |
|  7 |      8 |     C |      C | 2014-01-03 | 2014-01-04 |      2 |
|  8 |      9 |     C |      C | 2014-01-04 | 2014-01-04 |      1 |
|  9 |     10 |     C |      B | 2014-01-04 | 2014-01-05 |      2 |
| 11 |     12 |     B |      C | 2014-01-05 | 2014-01-06 |      2 |
| 12 |     13 |     C |      C | 2014-01-06 | 2014-01-06 |      1 |
| 13 |     14 |     C |      B | 2014-01-06 | 2014-01-07 |      2 |
| 19 |     20 |     B |      C | 2014-01-09 | 2014-01-10 |      2 |
| 20 |     21 |     C |      C | 2014-01-10 | 2014-01-10 |      1 |
| 21 | (null) |     C | (null) | 2014-01-10 |     (null) | (null) |

Open in new window

and here is the query for that:
with CTE as (
  select
  *
  , row_number() over(partition by clientid order by adate ASC) as rn
  from aTable
  )
select
        c1.rn
      , c2.rn c2rn
      , c1.acode
      , c2.acode c2code
      , c1.adate
      , c2.adate c2date
      , datediff(day,c1.adate, c2.adate) + 1 as dayz
from CTE c1
left join CTE c2 on c1.rn + 1 = c2.rn
where NOT (c1.acode = 'B' and c2.acode = 'B')
;

-- more details


CREATE TABLE aTable
	([aDate] date, [aCode] varchar(1), clientID int)
;
	
INSERT INTO aTable
	([aDate], [aCode])
VALUES
	('2014-01-01 00:00:00', 'A'),
	('2014-01-01 00:00:00', 'C'),
	('2014-01-02 00:00:00', 'B'),
	('2014-01-03 00:00:00', 'C'),
	('2014-01-04 00:00:00', 'C'),
	('2014-01-05 00:00:00', 'B'),
	('2014-01-06 00:00:00', 'C'),
	('2014-01-07 00:00:00', 'B'),
	('2014-01-08 00:00:00', 'B'),
	('2014-01-09 00:00:00', 'B'),
	('2014-01-10 00:00:00', 'C'),
	('2014-01-01 00:00:00', 'C'),
	('2014-01-02 00:00:00', 'B'),
	('2014-01-03 00:00:00', 'C'),
	('2014-01-04 00:00:00', 'C'),
	('2014-01-05 00:00:00', 'B'),
	('2014-01-06 00:00:00', 'C'),
	('2014-01-07 00:00:00', 'B'),
	('2014-01-08 00:00:00', 'B'),
	('2014-01-09 00:00:00', 'B'),
	('2014-01-10 00:00:00', 'C')
;

update aTable
set clientID = 1
;
http://sqlfiddle.com/#!6/ed097/1

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
chaauCommented:
I am not really sure if I understood your question correctly. This query gets you all B's with the number of days to the following C (or A):
;with crn as(
  SELECT *,
  ROW_NUMBER() OVER(ORDER BY dt) rn FROM Table1 ),
c as(
  SELECT dt, purchase, rn, ' ' as prePurchase, dt as preDt 
  FROM crn where rn = 1
  UNION ALL
  SELECT crn.dt, crn.purchase, crn.rn, c.purchase as prePurchase,
  CASE WHEN c.purchase = 'B' THEN c.preDT ELSE crn.dt END
  FROM crn INNER JOIN c ON c.rn + 1 = crn.rn)
select predt as dt, prepurchase as purchase, datediff(day, predt, dt) as diff
from c
where purchase in ('A', 'C') and prepurchase = 'B'

Open in new window

Results:
|                             DT | PURCHASE | DIFF |
|--------------------------------|----------|------|
| January, 02 2014 00:00:00+0000 |        B |    1 |
| January, 05 2014 00:00:00+0000 |        B |    1 |
| January, 07 2014 00:00:00+0000 |        B |    3 |

Open in new window

SQL Fiddle
0
awking00Commented:
What are the desired results for your sample data?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft SQL Server

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.