2012-10-03 21 views
1

我有這個疑問的Oracle SQL - 使用日期功能,提高查詢

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

回答

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

OK,現在最後的結果是這樣的:

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

這很好。感謝您花時間徹底解釋它。現在我可以使用這些知識了! – Americo

+0

不客氣。 –

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。當然完成未經測試:)

+0

它似乎沒有像Create_Dtime和date_of_concern之間的關係。看起來像date_of_concern是一個任意日期。 –

+0

@ Mt.Schneiders最初的查詢是從一年的開始到date_of_concern進行的運行總數。我正在(嘗試?)每年的每一天的運行總計,並計算每年的每一天的「date_of_concern」。目前還不太清楚需要什麼樣的範圍,或者它應該是與當前日期或其他範圍相關的滾動窗口...... – Glenn

+0

Date_Of_Concern是最重要的日期..因爲對於每個關注日期,只有關注日期7天內的「Trunc(P.Init_Dtime)」被計爲保留該日期。我以不同的方式使用了運行總數作爲跟蹤保留,但爲了達到此目的,我正在嘗試將所有date_of_concern作爲基礎。 – Americo