Take a look at the issue of islands and spaces and Itzik Ben-gan. There is a kit based on the method of obtaining the desired results.
I studied using ROW_NUMBER or RANK, but then I came across LAG and LEAD (introduced in SQL 2012), which are good. I have a solution below. This could definitely be simplified, but bearing in mind that several CTEs make my thinking process (as if mistaken, as it may be) easier to see. I just slowly transform the data into what I want. Uncomment one choice at a time if you want to see what each new CTE produces.
create table Junk (aDate Datetime, aLocation varchar(32)) insert into Junk values ('2000', 'Location1'), ('2001', 'Location1'), ('2002', 'Location1'), ('2004', 'Unknown'), ('2005', 'Unknown'), ('2006', 'Unknown'), ('2007', 'Location2'), ('2008', 'Location2'), ('2009', 'Location2'), ('2010', 'Location2'), ('2011', 'Location1'), ('2012', 'Location1'), ('2013', 'Location1'), ('2014', 'Location3') ;WITH StartsMiddlesAndEnds AS ( select aLocation, aDate, CASE(LAG(aLocation) OVER (ORDER BY aDate, aLocation)) WHEN aLocation THEN 0 ELSE 1 END [isStart], CASE(LEAD(aLocation) OVER (ORDER BY aDate, aLocation)) WHEN aLocation THEN 0 ELSE 1 END [isEnd] from Junk )
and he produces
aLocation start end Location1 2000 2002 Unknown 2004 2006 Location2 2007 2010 Location1 2011 2013 Location3 2014 2014
You do not have 2012? Then you can get the same StartSMiddlesAndEnds CTE using ROW_NUMBER:
;WITH NumberedRows AS ( SELECT aLocation, aDate, ROW_NUMBER() OVER (ORDER BY aDate, aLocation) [i] FROM Junk ) ,StartsMiddlesAndEnds AS ( select currentRow.aLocation, currentRow.aDate, CASE upperRow.aLocation WHEN currentRow.aLocation THEN 0 ELSE 1 END [isStart], CASE lowerRow.aLocation WHEN currentRow.aLocation THEN 0 ELSE 1 END [isEnd] from NumberedRows currentRow left outer join NumberedRows upperRow on upperRow.i = currentRow.i-1 left outer join NumberedRows lowerRow on lowerRow.i = currentRow.i+1 )