合并在一个单一的SQL表中的数据没有游标(Merging data in a single SQL

2019-08-05 07:08发布

我有一个ID列的表并与多个另一列。 一个ID可以有多个号码。 例如

ID | Number
 1 |  25
 1 |  26
 1 |  30
 1 |  24
 2 |  4
 2 |  8
 2 |  5

现在,基于这些数据,在一个新的表,我想有这样的

ID | Low | High 
1  |  24 |  26
1  |  30 |  30
2  |  4  |  5
2  |  8  |  8

正如你所看到的,我想所以,现在的低点是24合并,其中的数字是连续的任何数据,如24,25,26,高为26,然后30仍然是一个独立的范围。 我处理大量的数据,所以我宁愿不使用性能的缘故光标(这是我以前在做什么,并且速度变慢了不少)...什么是实现这一目标的最佳途径? 我不是SQL亲,所以我不知道是否有可用的功能,可以使这更容易,或者什么来完成,这将是最快的方式。

谢谢您的帮助。

Answer 1:

关键的观察是数字减去另一个序列的序列是一个常数。 我们可以通过生成另一个序列row_number 。 这标识的所有组:

select id, MIN(number) as low, MAX(number) as high
from (select t.*,
             (number - ROW_NUMBER() over (partition by id order by number) ) as groupnum
      from t
     ) t
group by id, groupnum

剩下的就是聚集。



Answer 2:

解决方案与CTE和递归:

WITH CTE AS (
  SELECT T.ID, T.NUMBER, T.NUMBER AS GRP
  FROM T 
  LEFT OUTER JOIN T T2 ON T.ID = T2.ID AND T.NUMBER -1 = T2.NUMBER 
  WHERE T2.ID IS NULL
  UNION  ALL
  SELECT T.ID, T.NUMBER, GRP
  FROM CTE 
  INNER JOIN T
  ON T.ID = CTE.ID AND T.NUMBER  = CTE.NUMBER + 1
)
SELECT ID, MAX( NUMBER ), MIN(NUMBER)
FROM CTE
GROUP BY ID, GRP

结果在fiddlesql



Answer 3:

我建议使用一个WHILE循环结构, 表变量 ,而不是光标。

例如,

DECLARE @TableVariable TABLE
(
    MyID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
    [ID] int,
    [Number] int
)

DECLARE @Count int, @Max int

INSERT INTO @TableVariable (ID, Number)
SELECT ID, Number
FROM YourSourceTable

SELECT @Count = 1, @Max = MAX(MyID)
FROM @TableVariable

WHILE @Count <= @Max
BEGIN

    ...do your processing here...


    SET @Count = @Count + 1

END


Answer 4:

CREATE TABLE Table1
    ([ID] int, [Number] int)
;

INSERT INTO Table1
    ([ID], [Number])
VALUES
    (1, 25),
    (1, 26),
    (1, 30),
    (1, 24),
    (2, 4),
    (2, 8),
    (2, 5)
;

    select ID, 
           MIN(Number)
         ,(SELECT MIN(Number) 
                  FROM (SELECT TOP 2 Number from Table1 WHERE ID =
                  T1.Id ORDER BY Number DESC) as DT)
    from Table1 as T1
    GROUP BY ID
    UNION 
    SELECT ID, MAX(Number), MAX(Number)
    FROM Table1 as T1
    GROUP BY ID;

活生生的例子



文章来源: Merging data in a single SQL table without a Cursor