2017-02-15 2 views
1

Если у меня есть список диапазонов в таблице, например.SQL Преобразование списка чисел в диапазоны в одном столбце

ID Number 
1  4 
1  5 
1  6 
1  7 
1  9 

Есть ли способ, чтобы поставить это в формате: «4-7,9» в один столбец VARCHAR с помощью SQL?

Спасибо.

+0

Какую версию сервера sql вы используете? –

+0

Есть ли другая колонка, чтобы найти заказ? –

+0

См. [Получение последовательных номеров в диапазоне от таблицы SQL Server] (http://stackoverflow.com/q/33061952/1110897). – Serge

ответ

1

Вы можете использовать ROW_NUMBER и XML PATH:

DECLARE @Mock TABLE (Id INT, Number INT) 
INSERT INTO @Mock   
VALUES 
(1, 4), 
(1, 5), 
(1, 6), 
(1, 7), 
(1, 9) 

;WITH CTE 
AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY Number) AS RowId,* 
    FROM @Mock 
) 

SELECT 
    STUFF(
    (
     SELECT   
      ',' + CAST(MIN(C.Number) AS VARCHAR(10)) + CASE WHEN MIN(C.Number) = MAX(C.Number) THEN '' ELSE '-' + CAST(MAX(C.Number) AS VARCHAR(10)) END 
     FROM 
      CTE C 
     GROUP BY    
      C.Number - C.RowId 
     FOR XML PATH ('') 

    ), 1, 1, '') Result 

Выход: 4-7,9

+0

Спасибо И! Это помогло – RA19

0

Учитывая у вас есть другой, чтобы найти порядок диапазонов

;WITH cte 
    AS (SELECT *, 
       Sum(CASE 
         WHEN number = prev_lag + 1 THEN 0 
         ELSE 1 
        END) 
        OVER(
        ORDER BY iden_col) AS grp 
     FROM (SELECT *, 
         Lag(number) 
          OVER(
          partition BY [ID] 
          ORDER BY iden_col) AS prev_lag 
       FROM Yourtable)a), 
    intr 
    AS (SELECT id, 
       CASE 
        WHEN Min(number) = Max(number) THEN Cast(Min(number) AS VARCHAR(50)) 
        ELSE Concat(Min(number), '-', Max(number)) 
       END AS intr_res 
     FROM cte 
     GROUP BY id, 
        grp) 
SELECT DISTINCT Id, 
       Stuff(concat_col, 1, 1, '') 
FROM intr a 
     CROSS apply (SELECT ',' + intr_res 
        FROM intr b 
        WHERE a.ID = b.ID 
        FOR xml path('')) cs (concat_col)