2015-09-13 81 views
0

我有一個由(column_a,column_b)分組並查詢聚合值的查詢。然後,我想通過column_a進行分組,並獲得以前彙總值的總和。SQL:如何使用GROUP BY獲取聚合的聚合?

用一個例子可能更清楚:

我們有3個表:項目開發者和貢獻者。每個項目都有很多的貢獻者,每個開發是一個貢獻者許多項目:

+======== projects =========+ +====== devs =======+ 
+--------------+------------+ +--------+----------+ 
| project_name | project_id | | dev_id | dev_name | 
+--------------+------------+ +--------+----------+ 
| parsalot  |   1 | |  1 | Ally  | 
| vimplug  |   2 | |  2 | Ben  | 
| gamify  |   3 | |  3 | Chris | 
+--------------+------------+ +--------+----------+ 
       +==== contributors ===+ 
       +------------+--------+ 
       | project_id | dev_id | 
       +------------+--------+ 
       |   1 |  2 | 
       |   1 |  3 | 
       |   2 |  1 | 
       |   2 |  2 | 
       |   3 |  3 | 
       +------------+--------+ 

我感興趣的多少工作進入每一個項目。我可以統計每個貢獻者的數量,但我希望更多地重視開發人員的貢獻,他們不會將時間花在其他項目上。因此,vimplug比parsalot更積極:每個項目都有兩個貢獻者,但vimplug(Ally)中的一個沒有其他任何東西,而parsalot的貢獻者都將他們的時間分配到其他項目中。

我已經構造的查詢,通過(項目,貢獻者)組和計算每個貢獻者「奉獻」的項目:

SELECT 
    projects.project_name, 
    devs.dev_name, 
    1/COUNT(contributions.project_id) as dedication 
FROM 
    projects 
     JOIN 
    contributors USING (project_id) 
     JOIN 
    devs USING (dev_id) 
     JOIN 
    contributors contributions USING (dev_id) 
GROUP BY projects.project_id , contributors.dev_id; 

它產生,

+--------------+----------+------------+ 
| project_name | dev_name | dedication | 
+--------------+----------+------------+ 
| parsalot  | Ben  |  0.5000 | 
| parsalot  | Chris |  0.5000 | 
| vimplug  | Ally  |  1.0000 | 
| vimplug  | Ben  |  0.5000 | 
| gamify  | Chris |  0.5000 | 
+--------------+----------+------------+ 

我真正想要的是什麼但是,是每個項目的總體奉獻,即

+--------------+------------------+ 
| project_name | total_dedication | 
+--------------+------------------+ 
| gamify  |   0.5000 | 
| parsalot  |   1.0000 | 
| vimplug  |   1.5000 | 
+--------------+------------------+ 

我(天真地)試圖將我的選擇語句更改爲

SELECT 
    projects.project_name, 
    SUM(1/COUNT(contributions.project_id)) as total_dedication 

但這不起作用(「無效使用組功能」)。有沒有辦法做到這一點,而不必做一個子選擇?

回答

2

只需使用一個子查詢:

select project_name, sum(dedication) 
from (<your query here>) q 
group by project_name; 
1

你是接近的解決方案,請使用以下命令:

SELECT project_name,sum(dedication) as total_dedication FROM (SELECT 
    projects.project_name, 
    devs.dev_name, 
    1/COUNT(contributions.project_id) as dedication 
FROM 
    projects 
     JOIN 
    contributors USING (project_id) 
     JOIN 
    devs USING (dev_id) 
     JOIN 
    contributors contributions USING (dev_id) 
GROUP BY projects.project_id , contributors.dev_id) as A GROUP BY project_name 
1

伊萬,

你問「有沒有一種方法,我可以做這不需要做一個子選擇「...是否有一個原因,你不能子選擇?

不幸的是,你需要使用子選擇,因爲你不能合併集合函數(這將是唯一能夠完成這個任務的方法)。請參閱:How to combine aggregate functions in MySQL?

因此,如其他答案所示,您必須使用子查詢。

+0

我一直希望避免一個子查詢,因爲我正在使用ActiveRecord在Rails應用程序的上下文中工作。子查詢並不是從ORM中抽出的最直接的東西,但我想在這種情況下是不可避免的。無論如何,我需要更好地使用子查詢。 – ivan