2011-11-18 41 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

相关问题