August 5, 2017 at 8:15 am
Hi All,
Thanks for any help I may receive as this is complex for me and am really struggle a best way to acheive this.
I am trying to get my data to a stage where i can do a one to one match for a row_number over stage.
I have two tables .
Table A | Table B | ||||||||
USERID | STARTDATE | END DATE | REF | USERID | STARTDATE | ENDDATE | TITLEID | ||
151 | 01/01/2005 | 01/01/2006 | 2168 | 151 | 01/01/2005 | 01/01/2006 | FPA1000 | ||
151 | 17/10/2007 | 151 | 02/01/2006 | 15/10/2007 | ASA1250 | ||||
151 | 16/10/2007 | BTA2500 | |||||||
161 | 10/10/2015 | 15/12/2015 | 161 | 10/10/2015 | 16/12/2015 | RTA2000 | |||
161 | 18/05/2016 | 161 | 19/12/2015 | 12/05/2016 | RTB1000 | ||||
161 | 16/05/2016 | BHA1000 |
If you look at USERID 151 it has in Table A it has the first row which can match with the first row from Table B. However the second row in Table A is a a match with the third row in Table B. So I would like to introduce a row in Table A based on the start date of the preceding row and the end in Table B on row 2. This has been made difficult by the fact that dates are not always match in both tables. The only items matching is the USERID and order of the dates. The stage I am trying to get the data to is shown below witht he ultimate goal of a one to one match.
Table A | Table B | ||||||||
USERID | STARTDATE | END DATE | REF | USERID | STARTDATE | ENDDATE | TITLEID | ||
151 | 01/01/2005 | 01/01/2006 | 2168 | 151 | 01/01/2005 | 01/01/2006 | FPA1000 | ||
151 | 01/01/2005 | 15/10/2007 | 2168 | 151 | 02/01/2006 | 15/10/2007 | ASA1250 | ||
151 | 17/10/2007 | 3400 | 151 | 16/10/2007 | BTA2500 | ||||
161 | 10/10/2015 | 15/12/2015 | 3120 | 161 | 10/10/2015 | 16/12/2015 | RTA2000 | ||
161 | 10/10/2015 | 12/05/2016 | 3120 | 161 | 19/12/2015 | 12/05/2016 | RTB1000 | ||
161 | 18/05/2016 | 6200 | 161 | 16/05/2016 | BHA1000 |
I'm not even sure if this is possible in one sweep. Thanks for any help.
August 8, 2017 at 7:08 am
Hi,
I know this scenario I have is quite a messy situation. I have managed to get my data to a better stage but have encountered what I am hoping is less of a complex situation.
I now have the data as below:-
USERID | StartDate | EndDate | Ref |
2168 | 25-Nov-04 | 26-Apr-06 | 1005909 |
2168 | 27-Apr-06 | 10-Jul-06 | NULL |
2168 | 11-Jul-06 | 25-Aug-06 | NULL |
2168 | 16-Apr-07 | 22-Nov-07 | 1005909 |
2168 | 16-May-08 | 02-Jan-10 | 1005909 |
2168 | 17-Jun-16 | 08-Dec-16 | 1012729 |
2168 | 09-Dec-16 | 02-Jan-17 | NULL |
2168 | 20-Feb-17 | 08-Jun-17 | 1012729 |
2168 | 09-Jun-17 | NULL | NULL |
2188 | 27-Apr-06 | 10-Jul-06 | NULL |
2188 | 11-Jul-06 | 25-Aug-06 | NULL |
2188 | 16-Apr-07 | 22-Nov-07 | 1005909 |
2188 | 16-May-08 | 02-Jan-10 | 1005909 |
2188 | 17-Jun-16 | 08-Dec-16 | 1012729 |
2188 | 09-Dec-16 | 02-Jan-17 | NULL |
2188 | 20-Feb-17 | 08-Jun-17 | 1012729 |
2188 | 09-Jun-17 | NULL | NULL |
I am trying to update the Ref column with a value from the previous row. If the previous row is NULL then it should go up another row and retrieve that value.
Wonder if anyone knows of a way to achieve this. Again thanks in advance.
August 8, 2017 at 7:43 am
Johnny D - Tuesday, August 8, 2017 7:08 AMHi,
I know this scenario I have is quite a messy situation. I have managed to get my data to a better stage but have encountered what I am hoping is less of a complex situation.
I now have the data as below:-
USERID StartDate EndDate Ref 2168 25-Nov-04 26-Apr-06 1005909 2168 27-Apr-06 10-Jul-06 NULL 2168 11-Jul-06 25-Aug-06 NULL 2168 16-Apr-07 22-Nov-07 1005909 2168 16-May-08 02-Jan-10 1005909 2168 17-Jun-16 08-Dec-16 1012729 2168 09-Dec-16 02-Jan-17 NULL 2168 20-Feb-17 08-Jun-17 1012729 2168 09-Jun-17 NULL NULL 2188 27-Apr-06 10-Jul-06 NULL 2188 11-Jul-06 25-Aug-06 NULL 2188 16-Apr-07 22-Nov-07 1005909 2188 16-May-08 02-Jan-10 1005909 2188 17-Jun-16 08-Dec-16 1012729 2188 09-Dec-16 02-Jan-17 NULL 2188 20-Feb-17 08-Jun-17 1012729 2188 09-Jun-17 NULL NULL I am trying to update the Ref column with a value from the previous row. If the previous row is NULL then it should go up another row and retrieve that value.
Wonder if anyone knows of a way to achieve this. Again thanks in advance.
Try an APPLY block with max date.
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
August 8, 2017 at 9:21 am
Hi ChrisM,
I have never used APPLY but I am not sure how this would solve the issue. After reading about APPLY it seems more like a inner join which would not give the back fill I am trying to achieve. Apologies if I have misunderstood how this is best used.
August 8, 2017 at 9:24 am
Johnny D - Tuesday, August 8, 2017 9:21 AMHi ChrisM,
I have never used APPLY but I am not sure how this would solve the issue. After reading about APPLY it seems more like a inner join which would not give the back fill I am trying to achieve. Apologies if I have misunderstood how this is best used.
Tell you what - knock up a sample data set and someone here will show you how it's done ๐
CREATE TABLE ...
followed by
INSERT INTO ...
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
August 8, 2017 at 9:33 am
a helping hand ๐ (courtesy of http://www.convertcsv.com/csv-to-sql.htm ...simple cut and paste !)
CREATE TABLE #yourdata(
USERID INTEGER NOT NULL
,StartDate DATETIME NOT NULL
,EndDate DATETIME
,Ref INTEGER
);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'25-Nov-04','26-Apr-06',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'27-Apr-06','10-Jul-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'11-Jul-06','25-Aug-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'16-Apr-07','22-Nov-07',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'16-May-08','02-Jan-10',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'17-Jun-16','08-Dec-16',1012729);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'09-Dec-16','02-Jan-17',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'20-Feb-17','08-Jun-17',1012729);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'09-Jun-17',NULL,NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'27-Apr-06','10-Jul-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'11-Jul-06','25-Aug-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'16-Apr-07','22-Nov-07',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'16-May-08','02-Jan-10',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'17-Jun-16','08-Dec-16',1012729);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'09-Dec-16','02-Jan-17',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'20-Feb-17','08-Jun-17',1012729);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'09-Jun-17',NULL,NULL);
SELECT * FROM #yourdata
DROP TABLE #yourdata
________________________________________________________________
you can lead a user to data....but you cannot make them think
and remember....every day is a school day
August 8, 2017 at 9:44 am
J Livingston SQL - Tuesday, August 8, 2017 9:33 AMa helping hand ๐ (courtesy of http://www.convertcsv.com/csv-to-sql.htm ...simple cut and paste !)
CREATE TABLE #yourdata(
USERID INTEGER NOT NULL
,StartDate DATETIME NOT NULL
,EndDate DATETIME
,Ref INTEGER
);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'25-Nov-04','26-Apr-06',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'27-Apr-06','10-Jul-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'11-Jul-06','25-Aug-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'16-Apr-07','22-Nov-07',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'16-May-08','02-Jan-10',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'17-Jun-16','08-Dec-16',1012729);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'09-Dec-16','02-Jan-17',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'20-Feb-17','08-Jun-17',1012729);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'09-Jun-17',NULL,NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'27-Apr-06','10-Jul-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'11-Jul-06','25-Aug-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'16-Apr-07','22-Nov-07',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'16-May-08','02-Jan-10',1005909);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'17-Jun-16','08-Dec-16',1012729);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'09-Dec-16','02-Jan-17',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'20-Feb-17','08-Jun-17',1012729);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2188,'09-Jun-17',NULL,NULL);SELECT * FROM #yourdata
DROP TABLE #yourdata
Hahaha thanks G!
SELECT *
FROM #yourdata y
OUTER APPLY (
SELECT Ref = MAX(Ref)
FROM #yourdata yi
WHERE yi.USERID = y.USERID
AND yi.StartDate < y.StartDate
AND y.Ref IS NULL
) x
ORDER BY USERID, StartDate
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
August 9, 2017 at 2:04 am
That seems to work ChrisM. Thanks.
Thanks J Livingstone too.
Just one other question. How do I get the original non NULL values to appear in the new column too along with the new values.
I'm still trying to understand how this is actually working as I've never come across APPLY until now.
Thanks
August 9, 2017 at 3:17 am
just a word of caution here....the solution is using MAX(ref) ...which works for your data as posted....but consider the following data. This does not deliver the "previous row"
CREATE TABLE #yourdata(
USERID INTEGER NOT NULL
,StartDate DATETIME NOT NULL
,EndDate DATETIME
,Ref INTEGER
);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'25-Nov-04','26-Apr-06',200);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'27-Apr-06','10-Jul-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'11-Jul-06','25-Aug-06',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'16-Apr-07','22-Nov-07',10);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'16-May-08','02-Jan-10',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'17-Jun-16','08-Dec-16',5);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'09-Dec-16','02-Jan-17',NULL);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'20-Feb-17','08-Jun-17',30);
INSERT INTO #yourdata(USERID,StartDate,EndDate,Ref) VALUES (2168,'09-Jun-17',NULL,NULL);
SELECT userid,
StartDate,
EndDate,
y.ref,
COALESCE(y.ref, x.ref) new_ref
FROM #yourdata y
OUTER APPLY
(
SELECT Ref = MAX(Ref)
FROM #yourdata yi
WHERE yi.USERID = y.USERID
AND yi.StartDate < y.StartDate
AND y.Ref IS NULL
) x
ORDER BY USERID, StartDate;
DROP TABLE #yourdata
________________________________________________________________
you can lead a user to data....but you cannot make them think
and remember....every day is a school day
August 9, 2017 at 5:19 am
Thanks J Livingstone.
You sure are a SQL Champion. I had a feeble effort myself using CASE and had some strange results.
August 9, 2017 at 8:41 am
Johnny D - Wednesday, August 9, 2017 5:19 AMThanks J Livingstone.You sure are a SQL Champion. I had a feeble effort myself using CASE and had some strange results.
I can assure you that I am far far from being any sort of SQL Champion !!!
did you run the example code I posted (which has changes to show where you may not get what you expect) ??
________________________________________________________________
you can lead a user to data....but you cannot make them think
and remember....every day is a school day
Viewing 11 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply