2011-11-18 74 views
0

我有一個查詢3個表:用戶的mysql統計數據 - 如何獲取每個日期範圍的列?

apiusers,用戶

  • 這些包含用戶ID和名稱。

download_stats:

此包含的用戶類型(1 =用戶,2 = apiusers),日期,文件downloaded_id。

我想要做的是得到一個佈局:

|用戶ID |名稱|下載1月的統計信息|下載統計二月

我目前正在此查詢,這需要永遠嘗試:

SELECT name,queryuserid,count(ROWA.id) ,count(ROWB.id) 
FROM (SELECT IFNULL(u.name, au.companyname) AS name,IFNULL(u.id, au.id) AS queryuserid 
    FROM apiusers as au, users as u 
    GROUP BY 2) AS users 
LEFT JOIN stats_download as ROWA ON ROWA.userid=queryuserid AND ROWA.date > date('2011-01-01') AND ROWA.date < date('2011-02-01') 
LEFT JOIN stats_download as ROWB ON ROWB.userid=queryuserid AND ROWB.date > date('2011-01-01') AND ROWB.date < date('2011-02-01') 
GROUP BY 2; 

有沒有要去這個更好的辦法?客戶希望支持按年,月和日「分組」輸出統計數據。所以那裏可能有30+的LEFT JOIN。

+0

我認爲,要獲得這種信息'行明智',你需要做大連接。您可以使用MONTH(ROWn.date)= 來優化日期選擇,而不是使用日期範圍。 – ethrbunny

+0

我也想知道是否有一種方法可以使用存儲過程在臨時表中累積這些信息,然後以這種逐行方式輸出它。否則,如果您想使查詢更簡單,您需要使用某種後置處理器(Perl或PHP等)來獲得此顯示。 – ethrbunny

+0

問題的第一個問題是,將APIUsers連接到用戶的內部查詢沒有JOIN條件,因此您得到一個笛卡爾產品......它們之間有什麼關係。此外,你的RowA和RowB是相同的......你是否打算實際上滾動日期來模擬每個月的下載統計數據(例如)? – DRapp

回答

2

這應該得到你的基礎,並運行一整年的樣本。看看這個模式。通過執行返回1或0的合格IF()條件的總和,您可以獲得每月的總計數。現在,如果您正在查找SIZE(如下載大小),而不是1,0,則可以替換fileSize而不是1,然後您將獲得總下載大小......將它們放在不同的列中,您可以同時擁有下載次數和下載次數。擴大日期範圍一年,只是繼續與模式...

SELECT 
     AllUsers.Name, 
     AllUsers.QueryUserID, 
     SUM(if(SD.Date BETWEEN '2011-01-01' and '2011-01-31', 1, 0)) as CountJan2011, 
     SUM(if(SD.Date BETWEEN '2011-02-01' and '2011-02-28', 1, 0)) as CountFeb2011, 
     SUM(if(SD.Date BETWEEN '2011-03-01' and '2011-03-31', 1, 0)) as CountMar2011, 
     SUM(if(SD.Date BETWEEN '2011-04-01' and '2011-04-30', 1, 0)) as CountApr2011, 
     SUM(if(SD.Date BETWEEN '2011-05-01' and '2011-05-31', 1, 0)) as CountMay2011, 
     SUM(if(SD.Date BETWEEN '2011-06-01' and '2011-06-30', 1, 0)) as CountJun2011, 
     SUM(if(SD.Date BETWEEN '2011-07-01' and '2011-07-31', 1, 0)) as CountJul2011, 
     SUM(if(SD.Date BETWEEN '2011-08-01' and '2011-08-31', 1, 0)) as CountAug2011, 
     SUM(if(SD.Date BETWEEN '2011-09-01' and '2011-09-30', 1, 0)) as CountSep2011, 
     SUM(if(SD.Date BETWEEN '2011-10-01' and '2011-10-31', 1, 0)) as CountOct2011, 
     SUM(if(SD.Date BETWEEN '2011-11-01' and '2011-11-30', 1, 0)) as CountNov2011, 
     SUM(if(SD.Date BETWEEN '2011-12-01' and '2011-12-31', 1, 0)) as CountDec2011 
    FROM 
     (select distinct 
       APIUsers.CompanyName as Name, 
       APIUsers.QueryUserID 
      from APIUsers 
     UNION 
     select 
       Users.Name, 
       Users.QueryUserID 
      from Users) AllUsers 

     LEFT JOIN stats_download SD 
      ON AllUsers.QueryUserID = SD.UserID 
     AND SD.Date BETWEEN '2011-01-01' and '2011-12-31' 
    GROUP BY 
     2; 
+0

這很快,很快。我要替換其他地方的其他代碼來做轉置,但我不確定我可以用它來解決這個問題。 他們的要求之一就是他們能夠在小時間範圍內篩選用戶/ api用戶,並讓所有人都出現。包括0下載的。由於這是基於stats_download表,它不會顯示是否有0個條目。 – neuron

+1

@neuron,我已經更新了查詢以預先查詢不同的用戶/名稱,併爲統計信息做了左連接。所以現在,你可以過濾特定的人和/或日期範圍。您可以在「AllUsers」預查中添加WHERE子句,或者調整日期。 – DRapp

+0

我很敬畏......在我按ctrl + c之前,我的舊查詢花了大約一分鐘,完全知道我無法在生產環境中使用它。這是與2個獨立的月份被拉入統計。 您的查詢:3秒鐘! (這是12個月被拉入..) – neuron

1

有一個更好的方法。

你需要做的只是一個與stats_download和彙總上月加盟,我認爲得到月從日期中提取月份的方法(每個數據庫都有自己的方法,你沒有指定你使用的是什麼)

(
SELECT name,queryuserid,count(stats_download.id) as cnt,GETMONTH(stats_download.date) as month 
FROM (SELECT IFNULL(u.name, au.companyname) AS name,IFNULL(u.id, au.id) AS queryuserid 
    FROM apiusers as au, users as u 
    GROUP BY 2) AS users 
LEFT JOIN stats_download ON stats_download.userid=queryuserid 
GROUP BY name, queryuserid, GETMONTH(stats_download.date) 
) as TableA 

那麼現在我們要根據不同羣體創建列的表,所以我們內部聯接與自身表(要快很多,因爲這個表是小)

Select name, queryuserid, A.cnt as January, B.cnt as February from TableA left join TableA as A on (TableA.queryuserid = A.queryuserid and A.month=1) left join TableA as B on (TableA.queryuserid = B.queryuserid and B.month=2) 

我沒有運行它,所以我可能有一些錯別字,但這是直接的灰。 希望它有幫助...

+0

從公共汽車上讀到這個,所以我還沒有嘗試過。但它看起來很有趣。 我使用mysql,所以我假設我會使用插入到第一個查詢,臨時表? – neuron

+0

好吧,我這樣寫,所以它會更容易理解,如果我要使用它,我會圍繞第一個包裝第二個查詢。這就是爲什麼我在第一個查詢中使用括號。但這更像是一個風格問題。 – idanzalz

+0

但是,如何使用「左連接」與您一起工作?那麼您是不是需要將TableA放在某個臨時的位置,或者在「From」和所有「左連接」查詢中都執行TableA查詢? – neuron

相關問題