Problem in Start And End Dates using CTE - sql

I have the below input
ID Activity Date
1 gardening 2011-01-01 00:00:00.000
1 gardening 2011-02-01 00:00:00.000
2 cooking 2011-03-01 00:00:00.000
2 cooking 2011-04-01 00:00:00.000
2 cooking 2011-05-01 00:00:00.000
1 gardening 2011-06-01 00:00:00.000
1 gardening 2011-07-01 00:00:00.000
The ddl is as under
Declare #t table(ID int,Activity Varchar(50),[Date] DATETIME)
Insert into #t Select 1,'gardening','01/01/2011' union all Select 1,'gardening','02/01/2011'
union all Select 2,'cooking','03/01/2011' union all Select 2,'cooking','04/01/2011'
union all Select 2,'cooking','05/01/2011' union all Select 1,'gardening','06/01/2011'
union all Select 1,'gardening','07/01/2011'
select * from #t
Expected output
ID ACTIVITY INITIAL_DATE END_DATE
1 gardening 01/01/2011 02/01/2011
1 gardening 02/01/2011 06/01/2011
1 gardening 06/01/2011 07/01/2011
2 cooking 03/01/2011 04/01/2011
2 cooking 04/01/2011 05/01/2011
So far I have done
;with cte as(Select Rn= ROW_NUMBER() Over(order by ID,[Date]),* from #t)
,cte2 as(
Select Rn
,ID,Activity,InitialDate =[Date],EndDate = [Date]
from cte where Rn =1
union all
Select c1.Rn
,c1.ID,c1.Activity,c1.Date,c1.Date
from cte2 c2
join cte c1
on c1.rn = c2.Rn+1
)
select ID,Activity,InitialDate,EndDate from cte2
but the output is not correct
ID Activity InitialDate EndDate
1 gardening 2011-01-01 00:00:00.000 2011-01-01 00:00:00.000
1 gardening 2011-02-01 00:00:00.000 2011-02-01 00:00:00.000
1 gardening 2011-06-01 00:00:00.000 2011-06-01 00:00:00.000
1 gardening 2011-07-01 00:00:00.000 2011-07-01 00:00:00.000
2 cooking 2011-03-01 00:00:00.000 2011-03-01 00:00:00.000
2 cooking 2011-04-01 00:00:00.000 2011-04-01 00:00:00.000
2 cooking 2011-05-01 00:00:00.000 2011-05-01 00:00:00.000
Help needed

;with cte as
(
select *,
row_number() over(partition by ID order by [Date]) as rn
from #t
)
select C1.ID,
C1.Activity,
C1.[Date] as INITIAL_DATE,
C2.[Date] as END_DATE
from cte as C1
inner join cte as C2
on C1.ID = C2.ID and
C1.rn + 1 = C2.rn
order by C1.ID, C1.[Date]

try this -
in oracle it is giving desired output..
please check for respective sql server function for lead () in oracle database
with cte as(Select * from #t)
(
SELECT * from
(
SELECT id,activity,
lead(date) over(partition be id,activity order by date desc) INITIAL_DATE,
date END_DATE
from cte
order by id,activity,date
)
WHERE INITIAL_DATE is not null
)

Related

Oracle sql query to group consecutive records by date

With the below sample data, I am trying to group record with same rate.
id start_date end_date rate
-----------------------------------------------------------------
1 01/01/2017 12:00:00 am 01/01/2017 12:00:00 am 300
1 02/01/2017 12:00:00 am 02/01/2017 12:00:00 am 300
1 03/01/2017 12:00:00 am 03/01/2017 12:00:00 am 300
1 04/01/2017 12:00:00 am 04/01/2017 12:00:00 am 1000
1 05/01/2017 12:00:00 am 05/01/2017 12:00:00 am 500
1 06/01/2017 12:00:00 am 06/01/2017 12:00:00 am 500
1 07/01/2017 12:00:00 am 07/01/2017 12:00:00 am 1000
1 08/01/2017 12:00:00 am 08/01/2017 12:00:00 am 1000
1 09/01/2017 12:00:00 am 09/01/2017 12:00:00 am 300
What I've tried :
select distinct id, mn_date, mx_date,rate
from (
select id, min(start_date) over (partition by grp order by start_date) mn_date,
max(end_date) over(partition by grp order by start_date desc) mx_date, rate
from (
select t.*, row_number() over(partition by id order by start_date) -row_number() over(partition by rate order by start_date)grp
from t
)
)
order by mn_date;
Output :
id mn_date mx_date rate
--------------------------------------------------------
1 01/01/2017 12:00:00 am 03/01/2017 12:00:00 am 300
1 04/01/2017 12:00:00 am 04/01/2017 12:00:00 am 1000
1 05/01/2017 12:00:00 am 06/01/2017 12:00:00 am 500
1 07/01/2017 12:00:00 am 09/01/2017 12:00:00 am 300
1 07/01/2017 12:00:00 am 09/01/2017 12:00:00 am 1000
Desired Output:
id mn_date mx_date rate
--------------------------------------------------------
1 01/01/2017 12:00:00 am 03/01/2017 12:00:00 am 300
1 04/01/2017 12:00:00 am 04/01/2017 12:00:00 am 1000
1 05/01/2017 12:00:00 am 06/01/2017 12:00:00 am 500
1 07/01/2017 12:00:00 am 08/01/2017 12:00:00 am 1000
1 09/01/2017 12:00:00 am 09/01/2017 12:00:00 am 300
Final result to group by consecutive dates: (Thanks to Gordon )
select id, min(start_date), max(end_date), rate
from (
select id, start_date, end_date, rate, seqnum_i-seqnum_ir grp, sum(x) over(partition by id order by start_date) grp1
from (
select t.*,
row_number() over (partition by id order by start_date) as seqnum_i,
row_number() over (partition by id, rate order by start_date) as seqnum_ir,
case when LEAD(start_date) over (partition by id order by start_date)= end_date + 1
then 0
else 1
end x
from t
)
)
group by id, grp+grp1, rate
order by min(start_date);
Assuming we can just use start_date to identify the adjacent records (i.e., there are no gaps), then you can use the difference of row numbers approach:
select id, min(start_date) as mn_date, max(end_date) as mx_date, rate
from (select t.*,
row_number() over (partition by id order by start_date) as seqnum_i,
row_number() over (partition by id, rate order by start_date) as seqnum_ir
from t
) t
group by id (seqnum_i - seqnum_ir), rate;
To see how this works, look at the results of the subquery. You should be able to "see" how the difference of the two row numbers defines the groups of adjacent records with the same rate.
I found that the last value wasn't being grouped correctly as the calculation of X wasn't handling the NULL return, so I changed it to this:
,CASE
WHEN LEAD (start_date)
OVER (PARTITION BY id ORDER BY start_date)
IS NULL
THEN
0
WHEN LEAD (start_date)
OVER (PARTITION BY id ORDER BY start_date) =
end_date + 1
THEN
0
ELSE
1
END
x

Finding the missing dates between two date ranges in SQL

I have a table like
ID StartDate EndDate
AAA 2017-03-17 00:00:00.000 2017-03-19 00:00:00.000
BB 2017-06-20 00:00:00.000 2017-06-25 00:00:00.000
CC 2017-05-13 00:00:00.000 2017-05-17 00:00:00.000
DD 2017-06-20 00:00:00.000 2017-05-27 00:00:00.000
EE 2017-03-01 00:00:00.000 2017-03-05 00:00:00.000
FF 2017-08-07 00:00:00.000 2017-08-11 00:00:00.000
i need the missing dates in between these ranges and the output table should be like
ID Date
AAA 2017-03-17 00:00:00.000 -- Start date for AAA
AAA 2017-03-18 00:00:00.000
AAA 2017-03-19 00:00:00.000 -- End date for AAA
BB 2017-06-20 00:00:00.000 -- start date for BB
BB 2017-06-21 00:00:00.000
BB 2017-06-22 00:00:00.000
BB 2017-06-23 00:00:00.000
BB 2017-06-24 00:00:00.000
BB 2017-06-25 00:00:00.000 -- End date for BB
You need to add loop to get dates between start and end dates , Example :
DECLARE #table table (ID Varchar(50), StartDate datetime,EndDate datetime)
insert into #table values ('AAA','2017-03-17 00:00:00.000',' 2017-03-19 00:00:00.000')
insert into #table values ('BB','2017-06-20 00:00:00.000 ',' 2017-06-25 00:00:00.000')
insert into #table values ('CC','2017-05-13 00:00:00.000 ',' 2017-05-17 00:00:00.000')
insert into #table values ('DD','2017-06-20 00:00:00.000 ',' 2017-05-27 00:00:00.000')
insert into #table values ('EE','2017-03-01 00:00:00.000 ',' 2017-03-05 00:00:00.000')
insert into #table values ('FF','2017-08-07 00:00:00.000 ',' 2017-08-11 00:00:00.000')
SELECT * FROM #table
SELECT id, StartDate FROM #table WHERE id='AAA'
union all
SELECT id, Dateadd(day,1,startdate) AS date FROM #table WHERE id='AAA' AND Dateadd(day,1,startdate)<EndDate
union all
SELECT id, EndDate FROM #table WHERE id='AAA'
union all
SELECT id, StartDate FROM #table WHERE id='BB'
union all
SELECT id, Dateadd(day,1,startdate) AS date FROM #table WHERE id='BB' AND Dateadd(day,1,startdate)<EndDate
union all
SELECT id, EndDate FROM #table WHERE id='BB'
union all
SELECT id, StartDate FROM #table WHERE id='CC'
union all
SELECT id, Dateadd(day,1,startdate) AS date FROM #table WHERE id='CC' AND Dateadd(day,1,startdate)<EndDate
union all
SELECT id, EndDate FROM #table WHERE id='CC'
union all
SELECT id, StartDate FROM #table WHERE id='DD'
union all
SELECT id, Dateadd(day,1,startdate) AS date FROM #table WHERE id='DD' AND Dateadd(day,1,startdate)<EndDate
union all
SELECT id, EndDate FROM #table WHERE id='DD'
union all
SELECT id, StartDate FROM #table WHERE id='EE'
union all
SELECT id, Dateadd(day,1,startdate) AS date FROM #table WHERE id='EE' AND Dateadd(day,1,startdate)<EndDate
union all
SELECT id, EndDate FROM #table WHERE id='EE'
union all
SELECT id, StartDate FROM #table WHERE id='FF'
union all
SELECT id, Dateadd(day,1,startdate) AS date FROM #table WHERE id='FF' AND Dateadd(day,1,startdate)<EndDate
union all
SELECT id, EndDate FROM #table WHERE id='FF'
Output:
id StartDate
AAA 2017-03-17 00:00:00.000
AAA 2017-03-18 00:00:00.000
AAA 2017-03-19 00:00:00.000
BB 2017-06-20 00:00:00.000
BB 2017-06-21 00:00:00.000
BB 2017-06-25 00:00:00.000
CC 2017-05-13 00:00:00.000
CC 2017-05-14 00:00:00.000
CC 2017-05-17 00:00:00.000
DD 2017-06-20 00:00:00.000
DD 2017-05-27 00:00:00.000
EE 2017-03-01 00:00:00.000
EE 2017-03-02 00:00:00.000
EE 2017-03-05 00:00:00.000
FF 2017-08-07 00:00:00.000
FF 2017-08-08 00:00:00.000
FF 2017-08-11 00:00:00.000
First, i created a calendar table based on your MIN and MAX date to get all the dates involved. Then i joined it to your table.
DECLARE #calendar AS TABLE ([Date] DATETIME)
DECLARE #maxDate AS DATETIME = (SELECT CASE WHEN MAX(StartDate) > MAX(EndDate)
THEN MAX(StartDate)
ELSE MAX(EndDate)
END FROM #YourTable)
DECLARE #minDate AS DATETIME = (SELECT CASE WHEN MIN(StartDate) < MIN(EndDate)
THEN MIN(StartDate)
ELSE MIN(EndDate)
END FROM #YourTable)
WHILE (#minDate < #maxDate)
BEGIN
INSERT INTO #calendar
VALUES (#minDate)
SET #minDate = DATEADD(DAY, 1, #minDate)
END
SELECT [Id], a.[Date]
FROM (Select [Date] FROM #calendar) a
LEFT JOIN #YourTable ON [Date] BETWEEN [StartDate] AND [EndDate]
WHERE [Id] IS NOT NULL
CREATE TABLE t
(
ID NVARCHAR(5) NOT NULL ,
StartDate DATETIME NOT NULL ,
EndDate DATETIME NOT NULL
);
GO
INSERT INTO dbo.t
( ID, StartDate, EndDate )
VALUES ( N'AAA', '2017-03-17 00:00:00.000', '2017-03-19 00:00:00.000' ),
( N'BB', '2017-06-20 00:00:00.000', '2017-06-25 00:00:00.000' ),
( N'CC', '2017-05-13 00:00:00.000', '2017-05-17 00:00:00.000' ),
( N'DD', '2017-06-20 00:00:00.000', '2017-05-27 00:00:00.000' ),
( N'EE', '2017-03-01 00:00:00.000', '2017-03-05 00:00:00.000' ),
( N'FF', '2017-08-07 00:00:00.000', '2017-08-11 00:00:00.000' );
WITH cte
AS ( SELECT ID ,
StartDate
FROM dbo.t
UNION ALL
SELECT cte.ID ,
DATEADD(DAY, 1, cte.StartDate)
FROM cte
INNER JOIN dbo.t ON t.ID = cte.ID
WHERE cte.StartDate < EndDate
)
SELECT cte.ID ,
cte.StartDate
FROM cte
ORDER BY cte.ID ,
cte.StartDate;
Result:
ID StartDate
----- -----------------------
AAA 2017-03-17 00:00:00.000
AAA 2017-03-18 00:00:00.000
AAA 2017-03-19 00:00:00.000
BB 2017-06-20 00:00:00.000
BB 2017-06-21 00:00:00.000
BB 2017-06-22 00:00:00.000
BB 2017-06-23 00:00:00.000
BB 2017-06-24 00:00:00.000
BB 2017-06-25 00:00:00.000
CC 2017-05-13 00:00:00.000
CC 2017-05-14 00:00:00.000
CC 2017-05-15 00:00:00.000
CC 2017-05-16 00:00:00.000
CC 2017-05-17 00:00:00.000
DD 2017-06-20 00:00:00.000
EE 2017-03-01 00:00:00.000
EE 2017-03-02 00:00:00.000
EE 2017-03-03 00:00:00.000
EE 2017-03-04 00:00:00.000
EE 2017-03-05 00:00:00.000
FF 2017-08-07 00:00:00.000
FF 2017-08-08 00:00:00.000
FF 2017-08-09 00:00:00.000
FF 2017-08-10 00:00:00.000
FF 2017-08-11 00:00:00.000

Applying LAG() to multiple rows with a null value

Given:
with
m as (
select 1 ID, cast('03/01/2015' as datetime) PERIOD_START, cast('3/31/2015' as datetime) PERIOD_END
union all
select 1 ID, '04/01/2015', '4/28/2015'
union all
select 1 ID, '05/01/2015', '5/31/2015'
union all
select 1 ID, '06/01/2015', '06/30/2015'
union all
select 1 ID, '07/01/2015', '07/31/2015'
)
,
a as (
SELECT 1 ID, cast('2015-03-13 14:17:00.000' as datetime) AUDIT_TIME, 'READ [2]' STATUS
UNION ALL
SELECT 1 ID, '2015-04-27 15:51:00.000' AUDIT_TIME, 'HELD [2]' STATUS
UNION ALL
SELECT 1 ID, '2015-07-08 17:54:00.000' AUDIT_TIME, 'COMPLETED [5]' STATUS
)
This query:
select m.ID,PERIOD_START,PERIOD_END
,a.AUDIT_TIME,STATUS
from m
LEFT OUTER JOIN a on m.id=a.id
and a.audit_time between m.period_start and m.period_end
generates this record set:
ID PERIOD_START PERIOD_END AUDIT_TIME STATUS
1 2015-03-01 00:00:00.000 2015-03-31 00:00:00.000 2015-03-13 14:17:00.000 READ [2]
1 2015-04-01 00:00:00.000 2015-04-28 00:00:00.000 2015-04-27 15:51:00.000 HELD [2]
1 2015-05-01 00:00:00.000 2015-05-31 00:00:00.000 NULL NULL
1 2015-06-01 00:00:00.000 2015-06-30 00:00:00.000 NULL NULL
1 2015-07-01 00:00:00.000 2015-07-31 00:00:00.000 2015-07-08 17:54:00.000 COMPLETED [5]
I need the 4/27/15 entry repeated for May and June:
ID PERIOD_START PERIOD_END AUDIT_TIME STATUS
1 2015-03-01 00:00:00.000 2015-03-31 00:00:00.000 2015-03-13 14:17:00.000 READ [2]
1 2015-04-01 00:00:00.000 2015-04-28 00:00:00.000 2015-04-27 15:51:00.000 HELD [2]
1 2015-05-01 00:00:00.000 2015-05-31 00:00:00.000 2015-04-27 15:51:00.000 HELD [2]
1 2015-06-01 00:00:00.000 2015-06-30 00:00:00.000 2015-04-27 15:51:00.000 HELD [2]
1 2015-07-01 00:00:00.000 2015-07-31 00:00:00.000 2015-07-08 17:54:00.000 COMPLETED [5]
Using the LAG() function:
select m.ID,PERIOD_START,PERIOD_END
,a.AUDIT_TIME
,LAG(audit_time) OVER (partition by m.ID order by period_start) PRIOR_AUDIT_TIME
,STATUS
,LAG(STATUS) OVER (partition by m.ID order by period_start) PRIOR_STATUS
from m
LEFT OUTER JOIN a on m.id=a.id
and a.audit_time between m.period_start and m.period_end
only works for a single row:
ID PERIOD_START PERIOD_END AUDIT_TIME PRIOR_AUDIT_TIME STATUS PRIOR_STATUS
1 2015-03-01 00:00:00.000 2015-03-31 00:00:00.000 2015-03-13 14:17:00.000 NULL READ [2] NULL
1 2015-04-01 00:00:00.000 2015-04-28 00:00:00.000 2015-04-27 15:51:00.000 2015-03-13 14:17:00.000 HELD [2] READ [2]
1 2015-05-01 00:00:00.000 2015-05-31 00:00:00.000 NULL 2015-04-27 15:51:00.000 NULL HELD [2]
1 2015-06-01 00:00:00.000 2015-06-30 00:00:00.000 NULL NULL NULL NULL
1 2015-07-01 00:00:00.000 2015-07-31 00:00:00.000 2015-07-08 17:54:00.000 NULL COMPLETED [5] NULL
Is there a way to do this without having to resort to a cursor?
You can do this with window functions:
with q as (
select m.ID, PERIOD_START, PERIOD_END, a.AUDIT_TIME, STATUS
from m LEFT OUTER JOIN
a
on m.id = a.id and
a.audit_time between m.period_start and m.period_end
)
select q.*,
max(status) over (partition by id, audit_grp) as imputed_status
from (select q.*,
max(audit_time) over (partition by id order by period_start) as audit_grp
from q
) q
The idea is to copy the audit_time value over, using max() as a cumulative window function. This then defines groups, so you can get the status as well.
ANSI supplies the IGNORE NULLSs directive to LAG(), but SQL Server does not (yet) support it.

Find range of dates within same column

I have a data set, which looks like this:
ResourceID RequirementId ProjectID Startdate EndDate BillingPercentage
-------------------- -------------------- -------------------- ----------------------- ----------------------- ---------------------------------------
1 5066 7505 2015-09-15 00:00:00.000 2015-09-30 00:00:00.000 50
2 4748 7499 2015-09-10 00:00:00.000 2015-09-20 00:00:00.000 50
I want to calculate range and corresponding billing % for that particular month my query is:
INSERT INTO #DateTimeline
SELECT #MonthStartDate AS OSTARTDATE,#MonthEndDate AS OENDDATE,0
INSERT INTO #DateTimeline
SELECT Startdate AS OSTARTDATE,EndDate AS OENDDATE,BillingPercentage From #RESOURCE_UNBILLED Order by Startdate
INSERT INTO #DateTimeline
SELECT EndDate AS OSTARTDATE,EndDate AS OENDDATE,BillingPercentage From #RESOURCE_UNBILLED Order by Startdate
And data looks like following:
SerialNo OSTARTDATE OENDDATE BillingPercentage
----------- ----------------------- ----------------------- ---------------------------------------
1 2015-09-01 00:00:00.000 2015-09-30 00:00:00.000 0
2 2015-09-10 00:00:00.000 2015-09-20 00:00:00.000 50
3 2015-09-15 00:00:00.000 2015-09-30 00:00:00.000 50
4 2015-09-20 00:00:00.000 2015-09-20 00:00:00.000 50
5 2015-09-30 00:00:00.000 2015-09-30 00:00:00.000 50
I want to retrive data like following
OSTARTDATE OENDDATE BillingPercentage
----------- ----------------------- ----------------------- ---------------------------------------
2015-09-01 00:00:00.000 2015-09-10 00:00:00.000 0
2015-09-10 00:00:00.000 2015-09-15 00:00:00.000 50
2015-09-15 00:00:00.000 2015-09-20 00:00:00.000 100
2015-09-20 00:00:00.000 2015-09-30 00:00:00.000 50
Please suggest how can I get this also can I use pivot here?
Use a table variable to store your #dateStamps with columns: SerialNo, OSTARTDATE and OENDDATE.
Try this query:
SELECT d.SerialNo, d.OSTARTDATE, d.OENDDATE
, ( SELECT SUM(t.BillingPercentage)
FROM yourTable t
WHERE d.OENDDATE BETWEEN t.Startdate AND t.EndDate
OR d.OSTARTDATE BETWEEN t.Startdate AND t.EndDate
OR (d.OSTARTDATE > t.Startdate AND d.OENDDATE < t.EndDate)
) AS BillingPercentage
FROM
#dateStamps d
My complete code is:
DECLARE #DatePart as int = 5
;WITH dateStamps AS (
SELECT 1 As SerialNo, CAST('2015-' + CONVERT(varchar, MONTH(MIN(t.Startdate))) + '-01 00:00:00.000' As datetime) AS OSTARTDATE
, CAST('2015-' + CONVERT(varchar, MONTH(MIN(t.Startdate))) + '-01 00:00:00.000' As datetime) + (#DatePart - 1) AS OENDDATE
FROM yourTable t
UNION ALL
SELECT ds.SerialNo + 1, ds.OSTARTDATE + #DatePart, ds.OSTARTDATE + (#DatePart * 2 - 1)
FROM dateStamps ds
WHERE MONTH(OSTARTDATE + #DatePart) <= MONTH(ds.OSTARTDATE)
)
SELECT d.SerialNo, d.OSTARTDATE, d.OENDDATE
, ( SELECT SUM(t.BillingPercentage)
FROM t
WHERE d.OENDDATE BETWEEN t.Startdate AND t.EndDate
OR d.OSTARTDATE BETWEEN t.Startdate AND t.EndDate
OR (d.OSTARTDATE > t.Startdate AND d.OENDDATE < t.EndDate)
) AS BillingPercentage
FROM
dateStamps d

Distinct values for a distinct datadate in SQL

In my table I sometimes have two dates with two values, but I just need one of them. Is there anyway to select a distinct value based on the distinct date?
example:
DATADATE ID
2008-06-30 00:00:00.000 12
2008-03-31 00:00:00.000 12
2007-12-31 00:00:00.000 3
2007-12-31 00:00:00.000 12
2007-09-30 00:00:00.000 3
2007-09-30 00:00:00.000 12
2007-06-30 00:00:00.000 3
2007-06-30 00:00:00.000 12
2007-03-31 00:00:00.000 3
2007-03-31 00:00:00.000 12
2006-12-31 00:00:00.000 3
2006-09-30 00:00:00.000 3
2006-06-30 00:00:00.000 3
What I need to get is this:
DATADATE ID
2008-06-30 00:00:00.000 12
2008-03-31 00:00:00.000 12
2007-12-31 00:00:00.000 12
2007-09-30 00:00:00.000 12
2007-06-30 00:00:00.000 12
2007-03-31 00:00:00.000 12
2006-12-31 00:00:00.000 3
2006-09-30 00:00:00.000 3
2006-06-30 00:00:00.000 3
Any help is really appreciated, thanks.
You could use group by:
select DATADATE
, max(IDs)
from YourTable
group by
DATADATE
If you are using sql server 2005+. Then you can do this:
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY ID ORDER BY DATADATE DESC) AS RowNbr,
Table1.*
FROM
Table1
)
SELECT
*
FROM
CTE
WHERE
CTE.RowNbr=1
EDIT
In the CTE function you can join or do what ever you cant to get the output you want. Like this:
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY Table1.ID ORDER BY Table2.DATADATE DESC) AS RowNbr,
Table1.*
FROM
Table1
JOIN Table2
ON Table1.ID = Table2.ID
)
SELECT
*
FROM
CTE
WHERE
CTE.RowNbr=1