Complicated queries are best solved by breaking it up into pieces and working step-by-step.
First let's create a query to find the key of the row we want to keep, by finding the most recent create date for each email then joining to get the Id:
select x.Email, x.CreateDate, x.Id
from myTable x
join (
select Email, max(CreateDate) as CreateDate
from myTable
group by Email
) y on x.Email = y.Email and x.CreateDate = y.CreateDate
Ok, now let's make a query to get duplicate email addresses:
select Email
from myTable
group by Email
having count(*) > 1
And join this query back to the table to get the keys for every row that has duplicates:
select x.Email, x.Id, x.CreateDate
from myTable x
join (
select Email
from myTable
group by Email
having count(*) > 1
) y on x.Email = y.Email
Great. Now all that is left is to join the first query with this one to get our result:
select keep.Email, keep.Id as IdKeep, keep.CreateDate as CreateDateOfIdKeep,
dup.Id as DuplicateId, dup.CreateDate as CreateDateOfDuplicateId
from (
select x.Email, x.CreateDate, x.Id
from myTable x
join (
select Email, max(CreateDate) as CreateDate
from myTable
group by Email
) y on x.Email = y.Email and x.CreateDate = y.CreateDate
) keep
join (
select x.Email, x.Id, x.CreateDate
from myTable x
join (
select Email
from myTable
group by Email
having count(*) > 1
) y on x.Email = y.Email
) dup on keep.Email = dup.Email and keep.Id <> dup.Id
Note the final keep.Id <> dup.Id
predicate on the join ensures we don't get the same row for both keep
and dup
.