For SQL 2005+, I think below will work
WITH DATES AS ( SELECT COL1, COL2, DATE, DATEADD(DAY, -1 * ROW_NUMBER() OVER(PARTITION BY COL1, COL2 ORDER BY DATE), DATE) AS GRP FROM YOUR_TABLE ) SELECT COL1, COL2, MIN(DATE) AS STARTDATE, MAX(DATE) AS ENDDATE FROM DATES GROUP BY COL1, COL2, GRP
If you have duplicate records, use DENSE_RANK() instead of ROW_NUMBER()
For SQL 2000, there is a helper query and its associated query.
SELECT COL1, COL2, MIN(DATE) AS STARTDATE, MAX(DATE) AS ENDDATE FROM (SELECT COL1, COL2, DATE, (SELECT MIN(DATE) FROM YOUR_TABLE B WHERE B.DATE >= A.DATE AND B.COL1 = A.COL1 AND B.COL2 = A.COL2 AND NOT EXISTS (SELECT * FROM YOUR_TABLE C WHERE C.COL1 = B.COL1 AND C.COL2 = B.COL2 AND DATEDIFF(DAY, B.DATE, C.DATE) = 1) ) AS GRP FROM YOUR_TABLE A ) GROUP BY COL1, COL2, GRP
source share