2

最初は、2 つの変数 x (グループ変数) と y があります。今度は、x の各グループ内で 1 から始まり、y が変化するたびに 1 ずつ増加する 3 番目の変数 z を作成したいと思います。次の例を参照してください。誰かがSQL Server 2008でそれを実現する方法を手伝ってもらえますか?

どうもありがとう!

x: a a a a a a a a b b b b b b b b
y: 0 0 0 1 0 0 2 3 0 1 0 0 2 3 0 0

最後に、次のように z を作成したいと思います。

x: a a a a a a a a b b b b b b b b
y: 0 0 0 1 0 0 2 3 0 1 0 0 2 3 0 0
z: 1 1 1 2 3 3 4 5 1 2 3 3 4 5 6 6
4

4 に答える 4

3

再帰的な CTEなどを使用できますrow_number

with C1 as
(
  select T1.id,
         T1.x,
         T1.y,
         row_number() over (partition by T1.x order by T1.id) as rn
  from table1 as T1
), C2 as
(
  select C1.id,
         C1.x,
         C1.y,
         C1.rn,
         1 as z
  from C1
  where C1.rn = 1
  union all
  select C1.id,
         C1.x,
         C1.y,
         C1.rn,
         C2.z + case when C1.y <> C2.y then 1 else 0 end
  from C1 
    inner join C2
      on C1.x = C2.x and
         C1.rn = C2.rn + 1
)
select x, y, z
from C2
order by id
option (maxrecursion 0);

CTE を再帰クエリのソースとして使用すると、パフォーマンスに問題が生じる可能性があることに注意してください。その場合は、CTE の結果をC1、主キーがオンの一時テーブルに入れることをお勧めします(x, rn)

SQL フィドル

于 2012-08-05T07:57:32.153 に答える
1

簡単な解決策は次のとおりです。

  declare @temp table ([row] int identity,[x] char,[y] int)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',1)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',2)
insert into @temp([x],[y]) values ('a',3)
insert into @temp([x],[y]) values ('b',0)
insert into @temp([x],[y]) values ('b',1)
insert into @temp([x],[y]) values ('b',0)
insert into @temp([x],[y]) values ('b',0)
insert into @temp([x],[y]) values ('b',2)
insert into @temp([x],[y]) values ('b',3)
insert into @temp([x],[y]) values ('b',0)
insert into @temp([x],[y]) values ('b',0)

--select * from @temp 

DECLARE @int int=0
;WITH CTE as(
select *,1 as incr from @temp where row=1 
union all
select t.*,
CASE WHEN t.x=c.x then CASE WHEN t.y=c.y then incr else incr+1 end else CASE WHEN t.y=c.y then @int else @int+1 end end as incr
from @temp t inner join CTE c
on t.row=c.row+1
)

select * from CTE
于 2012-08-05T12:35:34.147 に答える
1

これを行うことはできずrow_number() over (partition by ... order by ...)CTEクエリも機能しないようです。私は可能な限りカーソルの使用を避けたいと思っていますが、カーソルはあなたの状況にぴったりかもしれません:

declare @tbl table (id int, x char(1), y int, z int null)

declare
  @id int, @x char(1), @y int,
  @x2 char(1) = null, @y2 int = null, @z int

insert into @tbl (id, x, y) values
(1, 'a', 0), (2, 'a', 0), (3, 'a', 0),
(4, 'a', 1),
(5, 'a', 0), (6, 'a', 0),
(7, 'a', 2),
(8, 'a', 3),
(9, 'b', 0),
(10, 'b', 1),
(11, 'b', 0), (12, 'b', 0),
(13, 'b', 2),
(14, 'b', 3),
(15, 'b', 0), (16, 'b', 0)

declare cr cursor for
  select id, x, y
  from   @tbl
  order by  id

open cr
fetch next from cr into @id, @x, @y

while @@fetch_status = 0
begin
  set @z =
    case when @x2 is null or @x <> @x2
      then 1
      else
        case when @y = @y2
          then @z
          else @z + 1
        end
    end

  update @tbl
  set    z = @z
  where  id = @id

  set @x2 = @x
  set @y2 = @y

  fetch next from cr into @id, @x, @y
end

close cr
deallocate cr

select x, y, z
from   @tbl
order by id
于 2012-08-05T07:32:17.173 に答える
1

私のソリューションをミックスに投入すると思いました:

declare @temp table ([row] int identity,[x] char,[y] int)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',1)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',0)
insert into @temp([x],[y]) values ('a',2)
insert into @temp([x],[y]) values ('a',3)
insert into @temp([x],[y]) values ('b',0)
insert into @temp([x],[y]) values ('b',1)
insert into @temp([x],[y]) values ('b',0)
insert into @temp([x],[y]) values ('b',0)
insert into @temp([x],[y]) values ('b',2)
insert into @temp([x],[y]) values ('b',3)
insert into @temp([x],[y]) values ('b',0)
insert into @temp([x],[y]) values ('b',0)


declare @temp1 table
(
 [row] int
,[x] char
,[y] int
,[change] int
)
insert into @temp1
(
 [row]
,[x]
,[y]
,[change]
)
select 
 [t1].[row]
,[t1].[x]
,[t1].[y] 
,iif([t1].[x] = [t2].[x] and [t1].[y] <> [t2].[y],1,0) [change]
from @temp [t1]
left join @temp [t2] on [t2].[row] = [t1].[row] - 1

select * from @temp1

select 
 [row]
,[x]
,[y]
,(select sum([change]) from @temp1 [t2] where [t2].[row] <= [t1].[row] and [t2].[x] = [t1].[x]) + 1 [z]
from @temp1 [t1]
于 2012-08-05T08:02:22.453 に答える