I'm new to the site, and I'm hoping you can help...
I'm trying to stamp the LegNumber
from Table 2
into Table 1
based on the datetime
of the record in Table1
falling between the datetime
of the record(s) from Table 2
.
In my example, the records in Table 1
with a datetime that falls between 4/5/16 4:02 AM
and 4/7/16 6:53 AM
should be stamped with LegNumber
1862410
(from Table 2)
based on the datetimes
of 4/5/16 8:14 AM
thru 4/5/16 4:09 PM
. Hopefully, I haven't made this inquiry too confusing.
At first we create to cte's and gather time intervals, then select to show output:
;WITH LegsRowNumbers AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY LegStartDate ASC) as rn
FROM Table2 t2
), GetLegsIntervals AS (
SELECT l1.Tractor,
--Here may be another format, check CAST and CONVERT article on MSDN
CONVERT(datetime,l1.LegStartDate, 120) as LegStartDate,
DATEADD(minute,-1,l2.LegStartDate) as LegEndDate,
l1.LegNumber
FROM LegsRowNumbers l1
LEFT JOIN LegsRowNumbers l2
ON l2.rn = l1.rn+1
)
SELECT t.Tractor,
t.TollExitDateTime,
g.LegNumber
FROM Table1 t
LEFT JOIN GetLegsIntervals g
ON t.TollExitDateTime between g.LegStartDate and g.LegEndDate
Output:
Tractor TollExitDateTime LegNumber
1404 2016-04-03 05:21 AM NULL
1404 2016-04-03 05:34 AM NULL
1404 2016-04-03 06:28 AM NULL
1404 2016-04-03 02:36 PM NULL
1404 2016-04-03 03:13 PM NULL
1404 2016-04-03 03:29 PM NULL
1404 2016-04-05 08:14 AM 1862410
1404 2016-04-05 08:26 AM 1862410
1404 2016-04-05 09:26 AM 1862410
1404 2016-04-05 03:15 PM 1862410
1404 2016-04-05 03:53 PM 1862410
1404 2016-04-05 04:09 PM 1862410
You can change last query to UPDATE:
UPDATE t
SET LegNumber = g.LegNumber
FROM Table1 t
LEFT JOIN GetLegsIntervals g
ON t.TollExitDateTime between g.LegStartDate and g.LegEndDate
If you are one SQL Server 2012+, you can use the LEAD
to set the LegEndDate
for each:
create table TABLE1(TRACTOR integer, TOLLEXITDATETIME datetime);
create table TABLE2(TRACTOR integer, LEGSTARTDATE datetime, LEGNUMBER integer);
insert into TABLE1
select '1404', '4/3/2016 5:21:00 AM' union all
select '1404', '4/5/2016 5:21:00 AM' union all
select '1404', '4/6/2016 5:21:00 AM'
;
insert into TABLE2
select '1404', '4/4/2016 3:54:00 AM', 1862405 union all
select '1404', '4/5/2016 4:02:00 AM', 1862410 union all
select '1404', '4/7/2016 6:53:00 AM', 1865901
;
with TEMP_TABLE2(TRACTOR, LEGSTARTDATE, LEGENDDATE, LEGNUMBER)
AS(
select
TRACTOR,
LEGSTARTDATE,
lead(LEGSTARTDATE) over (partition by TRACTOR order by LEGSTARTDATE) LEGENDDATE,
LEGNUMBER
from TABLE2
)
select
t1.TRACTOR,
t1.TOLLEXITDATETIME,
t2.LEGNUMBER
from TABLE1 t1
left outer join TEMP_TABLE2 t2
on t1.TRACTOR = t2.TRACTOR
and t1.TOLLEXITDATETIME between t2.LEGSTARTDATE and coalesce(t2.LEGENDDATE, '12/31/9999')
Thank you mo2 for starter table code :) And thank you gofr1 for the ROW_NUMBER() OVER (ORDER BY LegStartDate ASC) as rn
because even though I use it all the time I completely blanked it.
Table I used for testing
create table Table2(Tractor integer, LegStartDate datetime, LegNumber integer primary key);
create table Table1(Tractor integer, TollExitDateTime datetime, LegNumber integer FOREIGN KEY REFERENCES Table2(Legnumber));
insert into TABLE1
select '1404', '4/3/2016 5:21:00 AM', NULL union all
select '1404', '4/3/2016 5:34:00 AM', NULL union all
select '1404', '4/3/2016 6:28:00 AM', NULL union all
select '1404', '4/3/2016 2:36:00 PM', NULL union all
select '1404', '4/3/2016 3:13:00 PM', NULL union all
select '1404', '4/3/2016 3:29:00 PM', NULL union all
select '1404', '4/5/2016 8:14:00 AM', NULL union all
select '1404', '4/5/2016 8:26:00 AM', NULL union all
select '1404', '4/5/2016 9:26:00 AM', NULL union all
select '1404', '4/5/2016 3:15:00 PM', NULL union all
select '1404', '4/5/2016 3:53:00 PM', NULL union all
select '1404', '4/5/2016 4:09:00 PM', NULL
;
insert into TABLE2
select '5000', '4/4/2016 3:54:00 AM', 5555555 union all --testing purpose
select '1404', '4/3/2016 5:21:00 AM', 8888888 union all --testing purpose
select '1404', '4/4/2016 3:54:00 AM', 1862405 union all
select '1404', '4/5/2016 4:02:00 AM', 1862410 union all
select '1404', '4/7/2016 6:53:00 AM', 1865901
;
This is the code I used to display, update, then display again for testing.
--This will just display what leg number goes with what
--I will probably be yelled at for not using joins. Normally I do but it worked perfectly fine in this situation to not so I did not bother to.
;WITH LegRows AS (SELECT *, ROW_NUMBER() OVER (ORDER BY t2a.LegStartDate ASC) as rn FROM Table2 t2a)
SELECT t1a.Tractor, t1a.TollExitDateTime, t1a.LegNumber, r1.LegStartDate, r1.LegNumber FROM Table1 t1a, LegRows r1, LegRows r2 WHERE t1a.TollExitDateTime BETWEEN r1.LegStartDate AND r2.LegStartDate AND r1.rn+1 = r2.rn
--This updates the leg information
;WITH LegRows AS (SELECT *, ROW_NUMBER() OVER (ORDER BY t2a.LegStartDate ASC) as rn FROM Table2 t2a)
UPDATE Table1 Set LegNumber = r1.LegNumber FROM Table1 t1a, LegRows r1, LegRows r2 WHERE t1a.TollExitDateTime BETWEEN r1.LegStartDate AND r2.LegStartDate AND r1.rn+1 = r2.rn
--This again displays what leg number goes with what to confirm the update
;WITH LegRows AS (SELECT *, ROW_NUMBER() OVER (ORDER BY t2a.LegStartDate ASC) as rn FROM Table2 t2a)
SELECT t1a.Tractor, t1a.TollExitDateTime, t1a.LegNumber, r1.LegStartDate, r1.LegNumber FROM Table1 t1a, LegRows r1, LegRows r2 WHERE t1a.TollExitDateTime BETWEEN r1.LegStartDate AND r2.LegStartDate AND r1.rn+1 = r2.rn
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.