我有以下代码:
create table #attr( enroll_month datetime ,cncl_mth datetime,
mth int,
tot_orders int,tot_cancel int, active_count int, attr_rate int , retn_rate
int
)
DECLARE
@enroll_mth datetime ,@cncl_mth datetime, @mth int ,
@tot_orders numeric, @tot_cancel numeric,
@attr_rate numeric(6,2), @retn_rate numeric(6,2),
@active_count int
DECLARE att_cursor CURSOR FOR
SELECT
d.Enroll_Month, d.cncl_mth, d.mth,
s.tot_orders, d.tot_cancel
FROM #Summary s with (nolock),
#Detail d with (nolock)
WHERE
s.Enroll_Month = d.Enroll_Month
OPEN att_cursor
FETCH NEXT FROM att_cursor INTO @enroll_mth, @cncl_mth, @mth, @tot_orders,
@tot_cancel
DECLARE
@old_enroll_mth datetime,
@old_cncl_mth datetime, @old_mth int, @month datetime ,
@intial varchar(1),
@old_active_cnt int, @old_tot_cancel int,
@old_retn_rate numeric(6,2), @old_attr_rate numeric(6,2),
@counter int
SELECT @old_enroll_mth = ''
SELECT @intial = 'Y'
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@old_enroll_mth <> @enroll_mth)
BEGIN
SELECT @active_count = @active_count - @tot_cancel
SELECT @intial = 'N'
END
ELSE
BEGIN
SELECT @active_count = @tot_orders - @tot_cancel
SELECT @intial = 'Y'
END
SELECT @retn_rate = (@active_count / @tot_orders) * 100
SELECT @attr_rate = 100 - @retn_rate
INSERT INTO #Attr (
enroll_month, cncl_mth, mth, tot_orders, tot_cancel,
active_count, attr_rate, retn_rate )
VALUES (
@enroll_mth, @cncl_mth, @mth, @tot_orders, @tot_cancel,
@active_count, @attr_rate, @retn_rate)
SELECT @old_enroll_mth = @enroll_mth
SELECT @old_mth = @mth
SELECT @old_retn_rate = @retn_rate
SELECT @old_attr_rate = @attr_rate
SELECT @old_active_cnt = @active_count
SELECT @old_cncl_mth = @cncl_mth
SELECT @old_tot_cancel = @tot_cancel
FETCH NEXT FROM att_cursor INTO @enroll_mth, @cncl_mth, @mth, @tot_orders,
@tot_cancel
END
CLOSE att_cursor
DEALLOCATE att_cursor
select * from #attr
将返回以下输出。
enroll_month cncl_mth mth tot_orders tot_cancel active_count attr_rate retn_rate
01/01/17 01/01/17 1 390 160 230 41 58
01/01/17 02/01/17 2 390 26 364 6 93
01/01/17 03/01/17 3 390 23 594 -52 152
它正在显示第mth = 1个活动计数的正确值。尽管对于mth = 2来说应该是(230-26 = 204),对于mth = 3来说应该是(204-23 = 181)。
我已经发布了两个脚本,以填充上述脚本中使用的摘要表和明细表。
create table #summary
(
enroll_month datetime,
tot_orders int
)
go
insert into #summary(enroll_month, tot_orders)
values ('2017-01-01 00:00:00.000', 390)
insert into #summary(enroll_month, tot_orders )
values ('2017-02-01 00:00:00.000', 615)
go
drop table #Detail
go
create table #detail
(
enroll_month datetime,
cncl_mnth datetime,
mth int,
tot_cancel int
)
go
insert into #detail(enroll_month,cncl_mnth,mth,tot_cancel)
values ('2017-01-01 00:00:00.000', '2017-01-01 00:00:00.000', 1, 160)
insert into #detail(enroll_month,cncl_mnth,mth,tot_cancel )
values ('2017-01-01 00:00:00.000','2017-02-01 00:00:00.000', 2, 26)
insert into #detail(enroll_month,cncl_mnth,mth,tot_cancel)
values ('2017-01-01 00:00:00.000','2017-03-01 00:00:00.000', 3, 23)
go
可以帮忙吗?
谢谢, 帕姆
答案 0 :(得分:0)
这有帮助吗??
create table #summary ( enroll_month datetime, tot_orders int )
insert into #summary(enroll_month, tot_orders) values ('2017-01-01 00:00:00.000', 390)
insert into #summary(enroll_month, tot_orders ) values ('2017-02-01 00:00:00.000', 615)
create table #detail ( enroll_month datetime, cncl_mnth datetime, mth int, tot_cancel int )
insert into #detail(enroll_month,cncl_mnth,mth,tot_cancel) values ('2017-01-01 00:00:00.000', '2017-01-01 00:00:00.000', 1, 160)
insert into #detail(enroll_month,cncl_mnth,mth,tot_cancel ) values ('2017-01-01 00:00:00.000','2017-02-01 00:00:00.000', 2, 26)
insert into #detail(enroll_month,cncl_mnth,mth,tot_cancel) values ('2017-01-01 00:00:00.000','2017-03-01 00:00:00.000', 3, 23)
SELECT
d.Enroll_Month, d.cncl_mnth, d.mth,
s.tot_orders, d.tot_cancel
into #tmp
FROM #Summary s with (nolock),
#Detail d with (nolock)
WHERE
s.Enroll_Month = d.Enroll_Month
;with cte
As
(
Select Enroll_Month,cncl_mnth,mth,tot_orders,tot_cancel,
tot_orders-tot_cancel as active_count,
FLOOR(100-(CAST((tot_orders-tot_cancel) AS FLOAT)/CAST(tot_orders AS FLOAT))*100) as attr_rate,
FLOOR((CAST((tot_orders-tot_cancel) AS FLOAT)/CAST(tot_orders AS FLOAT))*100) as retn_rate
from #tmp where mth=1
Union All
Select t.Enroll_Month,t.cncl_mnth,t.mth,t.tot_orders,t.tot_cancel,
c.active_count-t.tot_cancel as active_count,
FLOOR(100-(CAST((c.active_count-t.tot_cancel) AS FLOAT)/CAST(c.active_count AS FLOAT))*100) as attr_rate,
FLOOR((CAST((c.active_count-t.tot_cancel) AS FLOAT)/CAST(c.active_count AS FLOAT))*100) as retn_rate
from #tmp t
JOIN cte c on t.mth=c.mth+1
)
select * from cte
Drop Table #tmp
Drop table #summary
Drop table #detail
输出为:
Enroll_Month cncl_mnth mth tot_orders tot_cancel active_count attr_rate retn_rate
2017-01-01 00:00:00.000 2017-01-01 00:00:00.000 1 390 160 230 41 58
2017-01-01 00:00:00.000 2017-02-01 00:00:00.000 2 390 26 204 11 88
2017-01-01 00:00:00.000 2017-03-01 00:00:00.000 3 390 23 181 11 88
答案 1 :(得分:0)
我将使用common table expression (CTE)并使用SUM
和OVER子句产生总数。
WITH
summary
AS
(
SELECT tbl.* FROM (VALUES
( '01-Jan-2017', 390)
, ( '01-Feb-2017', 615)
) tbl ([enroll_month], [tot_orders])
)
,
details
AS
(
SELECT tbl.* FROM (VALUES
( '01-Jan-2017', '01-Jan-2017', 1, 160)
, ( '01-Jan-2017', '01-Feb-2017', 2, 26)
, ( '01-Jan-2017', '01-Mar-2017', 3, 23)
) tbl ([enroll_month], [cncl_mnth], [mth], [tot_cancel])
)
,
detail_active_count
AS
(
SELECT
d.[enroll_month]
, d.[cncl_mnth]
, s.[tot_orders]
, d.[mth]
, d.[tot_cancel]
, [active_count] = s.[tot_orders] - SUM(d.[tot_cancel]) OVER (PARTITION BY d.[enroll_month] ORDER BY d.[mth])
FROM
summary AS s
INNER JOIN details as d ON d.[enroll_month] = s.[enroll_month]
)
SELECT
c.*
, [attr_rate] = FLOOR(100 - (CAST((c.[active_count]) AS FLOAT) / CAST(c.[tot_orders] AS FLOAT)) * 100)
, [retn_rate] = FLOOR((CAST((c.[active_count]) AS FLOAT) / CAST(c.[tot_orders] AS FLOAT)) * 100)
FROM
detail_active_count AS c
答案 2 :(得分:0)
您的问题在这部分:
labix_mgo
您已经颠倒了所需的逻辑;).. 所以你需要像这样:
IF (@old_enroll_mth <> @enroll_mth)
BEGIN
SELECT @active_count = @active_count - @tot_cancel
SELECT @intial = 'N'
END
ELSE
BEGIN
SELECT @active_count = @tot_orders - @tot_cancel
SELECT @intial = 'Y'
END
已更新
样本数据
IF (@old_enroll_mth <> @enroll_mth)
BEGIN
SELECT @active_count = @tot_orders - @tot_cancel
SELECT @intial = 'Y'
END
ELSE
BEGIN
SELECT @active_count = @active_count - @tot_cancel
SELECT @intial = 'N'
END
使用上面的示例和您的DECLARE @summary TABLE (enroll_month datetime, tot_orders int)
DECLARE @detail TABLE (enroll_month datetime, cncl_mnth datetime, mth int, tot_cancel int)
DECLARE @attr TABLE (enroll_month datetime ,cncl_mth datetime, mth int, tot_orders int,tot_cancel int, active_count int, attr_rate int , retn_rate int)
insert into @summary(enroll_month, tot_orders) values
('2017-01-01 00:00:00.000', 390),
('2017-02-01 00:00:00.000', 615)
insert into @detail(enroll_month,cncl_mnth,mth,tot_cancel) values
('2017-01-01 00:00:00.000', '2017-01-01 00:00:00.000', 1, 160),
('2017-01-01 00:00:00.000','2017-02-01 00:00:00.000', 2, 26),
('2017-01-01 00:00:00.000','2017-03-01 00:00:00.000', 3, 23)
(修改了上面的逻辑-翻转了):
CURSOR
如果您想采用另一种没有DECLARE
@enroll_mth datetime ,@cncl_mth datetime, @mth int ,
@tot_orders numeric, @tot_cancel numeric,
@attr_rate numeric(6,2), @retn_rate numeric(6,2),
@active_count int
DECLARE att_cursor CURSOR FOR
SELECT
d.Enroll_Month, d.cncl_mnth, d.mth,
s.tot_orders, d.tot_cancel
FROM @summary s, @Detail d
WHERE
s.Enroll_Month = d.Enroll_Month
OPEN att_cursor
FETCH NEXT FROM att_cursor INTO @enroll_mth, @cncl_mth, @mth, @tot_orders, @tot_cancel
DECLARE
@old_enroll_mth datetime,
@old_cncl_mth datetime, @old_mth int, @month datetime ,
@intial varchar(1),
@old_active_cnt int, @old_tot_cancel int,
@old_retn_rate numeric(6,2), @old_attr_rate numeric(6,2),
@counter int
SELECT @old_enroll_mth = ''
SELECT @intial = 'Y'
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@old_enroll_mth <> @enroll_mth)
BEGIN
SELECT @active_count = @tot_orders - @tot_cancel
SELECT @intial = 'Y'
END
ELSE
BEGIN
SELECT @active_count = @active_count - @tot_cancel
SELECT @intial = 'N'
END
SELECT @retn_rate = (@active_count / @tot_orders) * 100
SELECT @attr_rate = 100 - @retn_rate
INSERT INTO @attr (enroll_month, cncl_mth, mth, tot_orders, tot_cancel, active_count, attr_rate, retn_rate )
VALUES (@enroll_mth, @cncl_mth, @mth, @tot_orders, @tot_cancel, @active_count, @attr_rate, @retn_rate)
SELECT @old_enroll_mth = @enroll_mth
SELECT @old_mth = @mth
SELECT @old_retn_rate = @retn_rate
SELECT @old_attr_rate = @attr_rate
SELECT @old_active_cnt = @active_count
SELECT @old_cncl_mth = @cncl_mth
SELECT @old_tot_cancel = @tot_cancel
FETCH NEXT FROM att_cursor INTO @enroll_mth, @cncl_mth, @mth, @tot_orders, @tot_cancel
END
CLOSE att_cursor
DEALLOCATE att_cursor
SELECT * FROM @attr
或CURSOR
的方法,则可以改用此方法:
CTE