1

我有这个查询

 --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

这给了我 1 行的结果:

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
4

2 回答 2

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

Obviously you will need a start date. Additionally, the number 5 has to be replaced by the number of dates you need, it could be a date range like

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'));

OK, now the final result would look like this:

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
于 2012-10-04T00:06:47.480 回答
0

I have a feeling your query can be simplified a lot. Here is an attempt to list day by day from the beginning of 2012. Depends what kind of range you are looking for.

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') )
                )
        )

The inner most query is an attempt to re-write the posted query counting from day 1 (Jan 1 2012). Then the next wrapper is supposed to do running totals for each subsequent day. The final wrapper is to enable the Perc_Retained. Completed untested of course :)

于 2012-10-04T01:11:00.310 回答