#sql #sql-server #tsql
#sql #sql-server #tsql
Вопрос:
Я заинтересован в разбивке PID на упорядоченные фрагменты на основе столбца CID. Пожалуйста, обратите внимание, что OID используется для упорядочения каждой подгруппы PID
GRP должен быть последовательным и начинаться с 0, если первый CID начинается с 0, в то время как GRP должен начинаться с 1, если GRP начинается с 1
PID OID CID GRP
----------- ----------- ----------- -----------
1 1 0 NULL
1 2 0 NULL
1 3 1 NULL
1 4 1 NULL
1 5 1 NULL
1 6 0 NULL
1 7 0 NULL
2 1 0 NULL
2 2 0 NULL
2 3 1 NULL
2 4 1 NULL
2 5 0 NULL
2 6 1 NULL
2 7 1 NULL
2 8 0 NULL
3 1 1 NULL
3 2 1 NULL
3 3 1 NULL
3 4 1 NULL
3 5 0 NULL
3 6 1 NULL
3 7 1 NULL
3 8 0 NULL
3 9 0 NULL
Решение приведенной выше таблицы приведено ниже, я хотел бы решить следующее с помощью T-SQL, однако я даже не уверен, что такая задача может быть возможной. По сути, я пытаюсь определить перерывы в повторении в столбце CID, как только перерыв будет идентифицирован, я хотел бы увеличить показатель GRP
PID OID CID GRP
----------- ----------- ----------- -----------
1 1 0 0
1 2 0 0
1 3 1 1
1 4 1 1
1 5 1 1
1 6 0 2
1 7 0 2
2 1 0 0
2 2 0 0
2 3 1 1
2 4 1 1
2 5 0 2
2 6 1 3
2 7 1 3
2 8 0 4
3 1 1 1
3 2 1 1
3 3 1 1
3 4 1 1
3 5 0 2
3 6 1 3
3 7 1 3
3 8 0 4
3 9 0 4
Вот пример кода для создания приведенной выше таблицы:
CREATE TABLE ##SOLUTION (PID INT, OID INT, CID INT, GRP INT)
insert into ##SOLUTION values
(1,1,0, 0),
(1,2,0, 0),
(1,3,1, 1),
(1,4,1, 1),
(1,5,1, 1),
(1,6,0, 2),
(1,7,0, 2),
(2,1,0, 0),
(2,2,0, 0),
(2,3,1, 1),
(2,4,1, 1),
(2,5,0, 2),
(2,6,1, 3),
(2,7,1, 3),
(2,8,0, 4),
(3,1,1, 1),
(3,2,1, 1),
(3,3,1, 1),
(3,4,1, 1),
(3,5,0, 2),
(3,6,1, 3),
(3,7,1, 3),
(3,8,0, 4),
(3,9,0, 4)
Заранее благодарю
Ответ №1:
Вы можете использовать lag()
для получения предыдущего значения (внутри каждого pid
). Затем условная совокупная сумма создает нужную группировку:
select s.*,
sum(case when prev_cid = cid then 0 else 1 end) over (partition by pid order by oid) as grp
from (select s.*,
lag(cid) over (partition by pid order by oid) as prev_cid
from solutions s
) s
Вот скрипка db<> .
Я должен добавить, что SQL Server позволяет очень легко обновлять эти значения с помощью обновляемых CTE:
with toupdate as (
select s.*,
sum(case when prev_cid = cid then 0 else 1 end) over (partition by pid order by oid) as new_grp
from (select s.*,
lag(cid) over (partition by pid order by oid) as prev_cid
from solution s
) s
)
update toupdate
set grp = new_grp;