2012-07-13 60 views
0

您對如何解決此問題有所瞭解嗎?每月總計顯示更新

這是DB的一個例子,我有:profile_table

user_id status points created_at 
01   1  20  2011-01-01 01:03:35 
02   1  50  2011-01-02 01:03:35 
03   1  800  2011-01-04 01:03:35 
04   1  152  2011-02-15 01:03:35 
05   1  388  2011-02-20 01:03:35 
06   0  40  2011-02-25 01:03:35 
07   1  246  2011-02-26 01:03:35 
08   1  335  2011-02-27 01:03:35 
09   1  521  2011-03-08 01:03:35 
10   1  5354  2011-03-14 01:03:35 
11   0  22  2011-03-18 01:03:35 
12   1  234  2011-04-03 01:03:35 
13   1  222  2011-04-05 01:03:35 
14   1  396  2011-04-24 01:03:35 

二表:spend_points

price_id spend_points created_at 
1   20    2011-01-01 01:03:35 
2   10    2011-01-02 01:03:35 
3   30    2011-01-05 01:03:35 
8   40    2011-01-06 01:03:35 
14   10    2011-02-03 01:03:35 
7   50    2011-02-06 01:03:35 
14   10    2011-02-07 01:03:35 
2   10    2011-03-03 01:03:35 
14   60    2011-03-12 01:03:35 
14   10    2011-04-07 01:03:35 
2   70    2011-04-12 01:03:35 
14   80    2011-04-15 01:03:35 
14   20    2011-04-21 01:03:35 

第一個表屬於一個組,這個組只能花與項目點'price_id'= 14。在spend_points表中,我們有所有項目花費,並且有大約14個。 我試圖構建的查詢應該顯示所有可以花費在price_id = 14上的用戶的數據。該表應該包含他們擁有的積分,花費積分和迄今爲止所有積分的總和。聽起來很容易,當你只需要這些數據,但對我來說問題是當我嘗試創建這個歷史時。每個新月都會顯示前一個月的更新以及上個月的更新等等。

狀態= 0表示不活躍和

所以最後的表應該是這樣的。

Detail     January February March April 
Total Active Users  3   7   9  12 
Total Inactive Users  0   1   2  2 
Total Point    807  2031  7928 8780  
Spend Points    0   20  80  190 
Points So Far    807  2051  8008 8970 

你們有什麼想法該怎麼做嗎? :'(

回答

1

這很長,但適合於RDBMS的意圖。它會這樣做......基於單一年的基礎......如果你的數據跨越了數年,只需在每個選擇/聯盟中添加適用的「年」where子句,查詢的前提是預先聲明每個月,所以我們知道「截止日期」在某個月的聚合情況下的位置(即:Jan是所有小於2月的總和,2月是總和到Mar等)。 每個人都需要每個月自己的樞軸彙總,這是什麼讓這個漫長的,但是,很容易得到你的結果。不是我如何計劃進行這樣的查詢,尤其是在一個大集合上 - 我希望每個月/每年的預期聚合具有「彙總」值的單個表,並且在適用的情況下,具有觸發器只需根據需要更新計數,點數。

set @jan := date("2011-01-01"); 
set @feb := date("2011-02-01"); 
set @mar := date("2011-03-01"); 
set @apr := date("2011-04-01"); 
set @may := date("2011-05-01"); 
set @jun := date("2011-06-01"); 
set @jul := date("2011-07-01"); 
set @aug := date("2011-08-01"); 
set @sep := date("2011-09-01"); 
set @oct := date("2011-10-01"); 
set @nov := date("2011-11-01"); 
set @decem := date("2011-12-01"); 
set @nextYr := date("2012-01-01"); 


select 
     'Active Users' as Detail, 
     sum(if(pt.status = 1 and pt.created_at < @feb, 1, 0)) January, 
     sum(if(pt.status = 1 and pt.created_at < @mar, 1, 0)) February, 
     sum(if(pt.status = 1 and pt.created_at < @apr, 1, 0)) March, 
     sum(if(pt.status = 1 and pt.created_at < @may, 1, 0)) April, 
     sum(if(pt.status = 1 and pt.created_at < @jun, 1, 0)) May, 
     sum(if(pt.status = 1 and pt.created_at < @jul, 1, 0)) June, 
     sum(if(pt.status = 1 and pt.created_at < @aug, 1, 0)) July, 
     sum(if(pt.status = 1 and pt.created_at < @sep, 1, 0)) August, 
     sum(if(pt.status = 1 and pt.created_at < @oct, 1, 0)) September, 
     sum(if(pt.status = 1 and pt.created_at < @nov, 1, 0)) October, 
     sum(if(pt.status = 1 and pt.created_at < @decem, 1, 0)) November, 
     sum(if(pt.status = 1 and pt.created_at < @nextYr, 1, 0)) December 
    from 
     profile_table pt 
union 
select 
     'Inactive Users' as Detail, 
     sum(if(pt.status = 0 and pt.created_at < @feb, 1, 0)) January, 
     sum(if(pt.status = 0 and pt.created_at < @mar, 1, 0)) February, 
     sum(if(pt.status = 0 and pt.created_at < @apr, 1, 0)) March, 
     sum(if(pt.status = 0 and pt.created_at < @may, 1, 0)) April, 
     sum(if(pt.status = 0 and pt.created_at < @jun, 1, 0)) May, 
     sum(if(pt.status = 0 and pt.created_at < @jul, 1, 0)) June, 
     sum(if(pt.status = 0 and pt.created_at < @aug, 1, 0)) July, 
     sum(if(pt.status = 0 and pt.created_at < @sep, 1, 0)) August, 
     sum(if(pt.status = 0 and pt.created_at < @oct, 1, 0)) September, 
     sum(if(pt.status = 0 and pt.created_at < @nov, 1, 0)) October, 
     sum(if(pt.status = 0 and pt.created_at < @decem, 1, 0)) November, 
     sum(if(pt.status = 0 and pt.created_at < @nextYr, 1, 0)) December 
    from 
     profile_table pt 
union 
select 
     'Total Points' as Detail, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @feb, 1, 0)) January, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @mar, 1, 0)) February, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @apr, 1, 0)) March, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @may, 1, 0)) April, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @jun, 1, 0)) May, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @jul, 1, 0)) June, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @aug, 1, 0)) July, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @sep, 1, 0)) August, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @oct, 1, 0)) September, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @nov, 1, 0)) October, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @decem, 1, 0)) November, 
     sum(pt.points * if(pt.status = 1 and pt.created_at < @nextYr, 1, 0)) December 
    from 
     profile_table pt 
union 
select 
     'Spend Points' as Detail, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @feb, 1, 0)) January, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @mar, 1, 0)) February, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @apr, 1, 0)) March, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @may, 1, 0)) April, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @jun, 1, 0)) May, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @jul, 1, 0)) June, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @aug, 1, 0)) July, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @sep, 1, 0)) August, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @oct, 1, 0)) September, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @nov, 1, 0)) October, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @decem, 1, 0)) November, 
     sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @nextYr, 1, 0)) December 
    from 
     spend_points sp 
union 
select 
     'Points So Far' as Detail, 
     PointsPerMonth.January + SpendPerMonth.January January, 
     PointsPerMonth.February + SpendPerMonth.February February, 
     PointsPerMonth.March + SpendPerMonth.March March, 
     PointsPerMonth.April + SpendPerMonth.April April, 
     PointsPerMonth.May + SpendPerMonth.May May, 
     PointsPerMonth.June + SpendPerMonth.June June, 
     PointsPerMonth.July + SpendPerMonth.July July, 
     PointsPerMonth.August + SpendPerMonth.August August, 
     PointsPerMonth.September + SpendPerMonth.September September, 
     PointsPerMonth.October + SpendPerMonth.October October, 
     PointsPerMonth.November + SpendPerMonth.November November, 
     PointsPerMonth.December + SpendPerMonth.December December 
    from 
     (select 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @feb, 1, 0)) January, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @mar, 1, 0)) February, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @apr, 1, 0)) March, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @may, 1, 0)) April, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @jun, 1, 0)) May, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @jul, 1, 0)) June, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @aug, 1, 0)) July, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @sep, 1, 0)) August, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @oct, 1, 0)) September, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @nov, 1, 0)) October, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @decem, 1, 0)) November, 
       sum(pt.points * if(pt.status = 1 and pt.created_at < @nextYr, 1, 0)) December 
      from 
       profile_table pt) PointsPerMonth, 
     (select 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @feb, 1, 0)) January, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @mar, 1, 0)) February, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @apr, 1, 0)) March, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @may, 1, 0)) April, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @jun, 1, 0)) May, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @jul, 1, 0)) June, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @aug, 1, 0)) July, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @sep, 1, 0)) August, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @oct, 1, 0)) September, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @nov, 1, 0)) October, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @decem, 1, 0)) November, 
       sum(sp.spend_points * if(sp.price_id = 14 and sp.created_at < @nextYr, 1, 0)) December 
      from 
       spend_points sp) SpendPerMonth 
+0

Ty非常DRapp :)我會試試看! – Nathre 2012-07-15 05:36:44

-1

在電子表格世界中,人們稱你想做一個「數據透視表」,你不會在沒有手動構建一些大規模醜陋的查詢的情況下從MySQL中獲取它 - 它只是不會你只需要在應用程序級別獲得每個月的值&就可以生成你的報告,類似地,那些運行總數最好的只是手動處理。