基于分组值合并段范围

时间:2017-07-13 21:31:46

标签: sql-server sql-server-2008 tsql

我有一个包含起点,终点和类似值的段表:

Bmp | Emp | SomeVal
0     1     1
1     2     1
2     3     2
3     4     2
4     5     1

我想合并(总结)这些记录,所以它们看起来像这样:

Bmp | Emp | SomeVal
0     2     1
2     4     2
4     5     1

为了解决这个问题,我简化了数据集。最终结果是我需要通过SomeVal列(在我的实际数据集中,大约有20列)分组的唯一行,其中段从Bmp到Emp拼接在一起,但不重叠。

我尝试了以下内容:

DECLARE @tbl TABLE (Bmp int, Emp int, SomeVal int)

INSERT INTO @tbl 
SELECT 0, 1, 1 UNION
SELECT 1, 2, 1 UNION
SELECT 2, 3, 2 UNION
SELECT 3, 4, 2 UNION
SELECT 4, 5, 1

SELECT MIN(Bmp) AS Bmp, Max(Emp) AS Emp, SomeVal FROM @tbl
GROUP BY SomeVal

不幸的是,它出现了如此错误:

Bmp | Emp | SomeVal
0     5     1
2     4     2

上面的查询仅在SomeVal的值不重复时才有效。我该如何修复我的sql?

所需的最低版本是SQL 2008。

2 个答案:

答案 0 :(得分:3)

您可以使用ROW_NUMBER()函数将开始组行与结束组行相关联。

DECLARE @tbl TABLE (Bmp int, Emp int, SomeVal int)

INSERT INTO @tbl 
SELECT 0, 1, 1 UNION
SELECT 1, 2, 1 UNION
SELECT 2, 3, 2 UNION
SELECT 3, 4, 2 UNION
SELECT 4, 5, 1

;WITH
[Begins] AS
(
    SELECT Bmp, SomeVal, ROW_NUMBER() OVER (ORDER BY Bmp) AS OrderNumber
    FROM @tbl AS [Begin]
    WHERE NOT EXISTS (
        SELECT 1
        FROM @tbl AS [Prev] 
        WHERE [Prev].Emp = [Begin].Bmp AND [Prev].SomeVal = [Begin].SomeVal)
),
[Ends] AS
(
    SELECT Emp, SomeVal, ROW_NUMBER() OVER (ORDER BY Emp) AS OrderNumber
    FROM @tbl AS [End]
    WHERE NOT EXISTS (
        SELECT 1
        FROM @tbl AS [Next]
        WHERE [Next].Bmp = [End].Emp AND [Next].SomeVal = [End].SomeVal)
)
SELECT [Begins].Bmp, [Ends].Emp, [Begins].SomeVal
FROM [Begins]
INNER JOIN [Ends]
    ON [Begins].OrderNumber = [Ends].OrderNumber;

答案 1 :(得分:-1)

这是另一种选择......

""