2016-10-13 3 views
3

У меня есть набор данных, как показано ниже.SQL-запрос для группировки данных

Code   Values 
521   1 
522   1 
523   1 
524   0 
525   0 
526   1 
527   1 

Я ожидаю выход что-то вроде ниже:

Group  CD  Values 
G1  521-523  1 
G2  524-525  0 
G3  526-527  1 
+1

Этот вопрос похож, и может помочь вам: http://stackoverflow.com/questions/19459274/sequential-group-by-in-sql-server –

ответ

1

Попробуйте это решение:

DECLARE @YourTable TABLE (Code INT, Value INT) 

INSERT INTO @YourTable 
VALUES 
(521,1), 
(522,1), 
(523,1), 
(524,0), 
(525,0), 
(526,1), 
(527,1) 

;WITH CTE AS 
(
    SELECT *, ROW_NUMBER() OVER(ORDER BY CODE) - ROW_NUMBER() OVER(PARTITION BY Value Order BY CODE) Grp 
    FROM @YourTable 
) 
SELECT ROW_NUMBER() OVER(ORDER BY(SELECT MIN(Code))) Grp 
     ,CAST(MIN(Code) AS VARCHAR(30)) +'-'+ CAST(MAX(Code) AS VARCHAR(30)) CD 
     ,MAX(Value) Val 
FROm CTE 
GROUP BY Grp 
+0

Awesome..This решение было полезным. – RAJ

1

Попробуйте с помощью LEAD(), ROW_NUMBER() и conditonal агрегации:

SELECT 'G' + ROUND((p.rnk + 1)/2) as group, 
     MAX(CASE WHEN p.rnk%2 = 1 THEN p.code END) + '-' + 
     MAX(CASE WHEN p.rnk%2 = 0 THEN p.code END) 
FROM (
    SELECT s.*, 
      ROW_NUMBER() OVER(ORDER BY s.code) as rnk 
    FROM (
     select t.*, 
       LEAD(t.values,1) OVER(ORDER BY t.code DESC) as last_val 
     FROM YourTable t) s 
    WHERE s.values <> s.last_val) p 
GROUP BY 'G' + ROUND((p.rnk + 1)/2) 
2

я был бы склонен использовать разность строки номеров:

select concat('G', row_number() over (order by min(value)) as grp, 
     concat(min(code), '-', max(code)) as codes, 
     value 
from (select t.*, 
      row_number() over (order by code) as seqnum_c, 
      row_number() over (partition by value order by code) as seqnum_vc 
     from t 
    ) t 
group by value, (seqnum_c - seqnum_vc); 
Смежные вопросы