2015-12-22 4 views
1

Пожалуйста, смотрите ниже DDL:заселить GroupID

CREATE TABLE #Test (ID) 
INSERT INTO #Test values (1) 
INSERT INTO #Test values (2) 
INSERT INTO #Test values (3) 
INSERT INTO #Test values (0) 
INSERT INTO #Test values (4) 
INSERT INTO #Test values (5) 
INSERT INTO #Test values (6) 
INSERT INTO #Test values (8) 
INSERT INTO #Test values (12) 
INSERT INTO #Test values (19) 
INSERT INTO #Test values (0) 
INSERT INTO #Test values (44) 

Ищу для запроса, который выводит следующее (GroupID, ID).

1,1 
1,2 
1,3 
2,4 
2,5 
2,6 
2,8 
2,12 
2,19 
3,44 

Ряд с идентификатором 0 разбивает группы.

Запрос будет выглядеть примерно так:

select GroupID = row_number() over (order by (select null)),ID from #Test 

потребности Система GroupID быть разделен с использованием строк, которые имеют нулевое значение. Вышеприведенный запрос просто создает новый GroupID для каждой строки.

+1

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

+4

У вас есть столбец и/или значение, которое будет хранить данные в этом конкретном порядке? Данные не заказываются без указания того, чтобы не было простого способа гарантировать нулевые значения в этих точках. – Taryn

+0

@TabAlleman Нет, если вы хотите разбить на нулевые значения. – Taryn

ответ

2

Таблицы SQL представляют собой неупорядоченные множества. Таким образом, вы не можете делать то, что хотите, со своей структурой данных, потому что у нее нет порядка. Тем не менее, это легко исправить, добавив столбец идентификаторов:

CREATE TABLE #Test (
    TestId int identity(1, 1) primary key, -- the primary key is not strictly necessary, just my habit with identity columns. 
    Val int 
); 

(я взял на себя смелость переименования столбца в val вместо id, чтобы избежать путаницы.) Столбец идентификации фиксирует порядок вставки.

Группа рассчитывается как количество нулей до заданного значения. В SQL Server 2012+, это легко сделать, используя накопленную сумму:

select t.*, 
     1 + sum(case when val = 0 then 1 else 0 end) over (order by testid) as groupid 
from #test t; 

Я заметил, что вы не хотите, нулей в выводе, для этой цели использовать подзапрос после нарастающего итога:

select * 
from (select t.*, 
      1 + sum(case when val = 0 then 1 else 0 end) over (order by testid) as groupid 
     from #test t 
    ) t 
where val <> 0; 
+0

Более анонимные downvotes на правильный ответ. Кажется, сегодня это образец. –

+2

Учитывая, что вы являетесь пользователем почти 4 года, вы действительно должны просто игнорировать downvotes. Комментирование не уведомляет избирателя, просто отмахивается от него. – Taryn

+0

@bluefeet. , , Приветствия. Я ценю обратную связь, но обнаруживаю, что анонимные downvotes раздражают (и хотят, чтобы Stack Exchange обескураживал их). Иногда, я буду неделями без downvotes. Сегодня у меня есть шесть (семь, если я считаю разворот) downvotes по трем вопросам, все без объяснения причин, и все неясно (для меня) почему. Это просто наблюдение. –

Смежные вопросы