我有这个查询
--Retention by DOC,Users created >= Jan 1,2012--
Select
One.Date_Of_Concern,
Two.Users,
One.Retained,
Round(One.Retained/Two.Users,4) as Perc_Retained
From
(
Select
To_Date('2012-sep-09','yyyy-mon-dd')As Date_Of_Concern,
Count(P.Player_Id) As Retained
From Player P
Where
Trunc(P.Create_Dtime) >= To_Date('2012-Jan-01','yyyy-mon-dd')
And
(To_Date('2012-sep-09','yyyy-mon-dd')-Trunc(P.Init_Dtime))<=7
) One
Inner Join
(
Select
To_Date('2012-sep-09','yyyy-mon-dd')As Date_Of_Concern,
Count(P.Player_Id) As Users
From Player P
Where
Trunc(P.Create_Dtime) >= To_Date('2012-Jan-01','yyyy-mon-dd')
) Two On One.Date_Of_Concern = Two.Date_Of_Concern
给了我一行的结果:
Date_Of_Concern USERS RETAINED PERC_RETAINED
09-Sep-12 449773 78983 0.1756
我想通过添加某种日期更改方法来改进此查询。这样,我不必每次都为09-sep-12,10-sep-12,11-sep-12运行查询,依此类推。相反,它将显示在同一个查询中,如下所示:
Date_Of_Concern USERS RETAINED PERC_RETAINED
09-Sep-12 449773 48783 0.1756
10-Sep-12 449773 46777 0.1600
11-Sep-12 440773 44852 0.1500
12-Sep-12 349773 42584 0.1400
答案 0 :(得分:1)
嗯,根据给定的信息,我不知道您是否有任何桌子可以加入并带上这些日期。但是,如果你不这样做,你可以试试这个:
我们必须生成行并以顺序形式重现日期。但首先,让我们看一下如何生成行:
生成5行:
SELECT rownum
FROM dual
CONNECT BY LEVEL <= 5;
ROWNUM
----------
1
2
3
4
5
现在,应用它来重现日期的数据源:
SELECT to_date('2012-sep-09','yyyy-mon-dd') + (rownum -1) as Date_Of_Concern
FROM dual
CONNECT BY LEVEL <= 5;
Date_Of_Concern
----------
2012-sep-09
2012-sep-10
2012-sep-11
2012-sep-12
2012-sep-13
显然你需要一个开始日期。此外,数字5必须由您需要的日期数替换,它可以是日期范围,如
SELECT to_date('2012-sep-09','yyyy-mon-dd') + (rownum -1) date
FROM dual
CONNECT BY LEVEL <= (to_date('2012-sep-20','yyyy-mon-dd') - to_date('2012-sep-09','yyyy-mon-dd'));
好的,现在最终结果如下:
SELECT both.Date_Of_Concern,
both.Retained,
both.Users,
Round(both.Retained/both.Users,4) as Perc_Retained
FROM (select Date_Of_Concern,
(Select Count(P.Player_Id) As Retained
From Player P
Where Trunc(P.Create_Dtime) >= To_Date('2012-Jan-01','yyyy-mon-dd')
And (Date_Of_Concern-Trunc(P.Init_Dtime))<=7) Retained,
(Select Count(P.Player_Id) As Users
From Player P
Where Trunc(P.Create_Dtime) >= To_Date('2012-Jan-01','yyyy-mon-dd')
) Users
from (SELECT to_date('2012-sep-09','yyyy-mon-dd') + (rownum -1) Date_Of_Concern,
FROM dual
CONNECT BY LEVEL <= 5)) both
答案 1 :(得分:0)
我感觉您的查询可以简化很多。这是尝试从2012年初开始逐日列出。取决于您正在寻找的范围。
SELECT date_of_concern
,Running_Total_Users AS Users
,Running_Total_Retained As Retained
,ROUND(Running_Total_Retained / Running_Total_Users, 4) AS Perc_Retained
FROM ( SELECT date_of_concern
,SUM(Users) OVER( ORDER BY date_of_concern
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW ) AS Running_Total_Users
,SUM(Retained) OVER( ORDER BY date_of_concern
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW ) AS Running_Total_Retained
FROM ( SELECT TRUNC(Create_Dtime) date_of_concern
,COUNT(Player_Id) Users
,SUM( CASE WHEN (TRUNC(Create_Dtime) - TRUNC(Init_Dtime)) <= 7 THEN 1 ELSE 0 END ) AS Retained
FROM player ON ( TRUNC(.Create_Dtime) >= TO_DATE('2012', 'YYYY') )
)
)
最内部查询是尝试重新编写从第1天(2012年1月1日)算起的已发布查询。然后,下一个包装器应该为每个后续日运行总计。最后的包装器是启用Perc_Retained
。当然未经测试完成:)