SQL Server - 101和11的组位模式

时间:2013-09-10 14:39:42

标签: sql sql-server

在'bit'列中,只要有一组连续的1或'101',我想将这些值分组。例如:11是一个组。 101是一组。 110111是一个群体。 00100不是一个团体。以下是一些例子:

实施例1,:

╔════╦══════╦═══════╗
║ ID ║  BIT ║ GROUP ║
╠════╬══════╬═══════╣
║  1 ║    0 ║     1 ║
║  2 ║    1 ║     2 ║
║  3 ║    1 ║     2 ║
║  4 ║    0 ║     2 ║
║  5 ║    1 ║     2 ║
║  6 ║    0 ║     3 ║
║  7 ║    0 ║     4 ║
╚════╩══════╩═══════╝

例2:

╔════╦══════╦═══════╗
║ ID ║  BIT ║ GROUP ║
╠════╬══════╬═══════╣
║  1 ║    0 ║     1 ║
║  2 ║    0 ║     2 ║
║  3 ║    1 ║     3 ║
║  4 ║    1 ║     3 ║
║  5 ║    1 ║     3 ║
║  6 ║    0 ║     4 ║
║  7 ║    0 ║     5 ║
╚════╩══════╩═══════╝

实施例3:

╔════╦══════╦═══════╗
║ ID ║  BIT ║ GROUP ║
╠════╬══════╬═══════╣
║  1 ║    1 ║     1 ║
║  2 ║    1 ║     1 ║
║  3 ║    0 ║     1 ║
║  4 ║    1 ║     1 ║
║  5 ║    1 ║     1 ║
║  6 ║    1 ║     1 ║
║  7 ║    0 ║     2 ║
╚════╩══════╩═══════╝

注意:打破模式的每一行都有自己的组。

我真的被困在这,任何人都有任何想法?

2 个答案:

答案 0 :(得分:2)

我认为这有效:

--create table #a (id int,b bit);

--insert #a select 1,0;
--insert #a select 2,0;
--insert #a select 3,1;
--insert #a select 4,1;
--insert #a select 5,1;
--insert #a select 6,0;
--insert #a select 7,0;

--delete #a;

--insert #a select 1,1;
--insert #a select 2,1;
--insert #a select 3,0;
--insert #a select 4,1;
--insert #a select 5,1;
--insert #a select 6,1;
--insert #a select 7,0;


with q as (
    select id,b,b1,b2,b3,newgroup
    from #a a
    outer apply (select p1=b from #a x where x.id=a.id-1) p1
    outer apply (select p2=b from #a x where x.id=a.id-2) p2
    outer apply (select p3=b from #a x where x.id=a.id+1) p3
    cross apply (select b1=isnull(p1,0),b2=isnull(p2,0),b3=isnull(p3,0)) b
    cross apply (select newgroup=case when b=0 then case when b1=0 or b3=0 then 1 else 0 end when b=1 then case when b1=0 and b2=0 then 1 else 0 end end) n
)
select id,b,g
from #a a
cross apply (select g=count(*) from q where q.id<=a.id and newgroup=1) q
;

答案 1 :(得分:0)

试试这个:

select Id, [Bit]
    , case gr
        when 0 then Id - row_number() over(partition by gr order by Id)
        else row_number() over(partition by gr order by Id) end as [Group]
from (
    select Id, b0 as [Bit]
        , case when
               (b0 = 1 and b1 = 1)
            or (b0 = 1 and b1 = 0 and b2 = 1)
            or (b_1 = 1 and b0 = 0 and b1 = 1) then 0 else 1 end as gr
    from (
        select Id+x as Id
            , min(case x when -1 then b end) b_1
            , min(case x when 0 then b end) b0
            , min(case x when 1 then b end) b1
            , min(case x when 2 then b end) b2
        from (
            select Id, cast([Bit] as int) as b
            from MyTable
        ) T
        cross join (values(-1),(0),(1),(2))x(x)
        group by Id+x
        having min(case x when 0 then b end) is not null
    ) T
) T
order by Id