Since you did not specify which version of SQL Server, I have several solutions. If you are still downloading SQL Server 2005, then Giorgi uses CROSS APPLY very well.
Note. . For both solutions, I use the where clause to filter out invalid values, so even if the data is bad and the lines overlap, they will ignore these values.
My version of the table
DECLARE @T TABLE (variable_name CHAR, start_no INT, end_no INT) INSERT INTO @T VALUES ('x', 10, 20), ('x', 30, 50), ('x', 60, 70), ('y', 1, 3), ('y', 7, 8);
Solution for SQL Server 2012 and higher
SELECT * FROM ( SELECT variable_name, LAG(end_no,1) OVER (PARTITION BY variable_name ORDER BY start_no) + 1 AS start_range, start_no - 1 AS end_range FROM @T ) A WHERE end_range > start_range
Solution for SQL 2008 and higher
WITH CTE AS ( SELECT ROW_NUMBER() OVER (PARTITION BY variable_name ORDER BY start_no) row_num, * FROM @T ) SELECT A.variable_name, B.end_no + 1 AS start_range, A.start_no - 1 AS end_range FROM CTE AS A INNER JOIN CTE AS B ON A.variable_name = B.variable_name AND A.row_num = B.row_num + 1 WHERE A.start_no - 1 > B.end_no + 1
Stephan
source share