最初,我有两个变量x(组变量)和y,现在我想创建第三个变量z,每个x组中的每个从1开始,每当y变化时增加1。请参阅以下示例。有人可以帮助我在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
答案 0 :(得分:3)
您可以使用recursive 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)
上带有主键的临时表中。
答案 1 :(得分: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
答案 2 :(得分: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]
答案 3 :(得分: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