2017-02-20 64 views
1

表看起來是這樣的:如何組相同的表不同的外部查詢和子查詢

id | number  | provider| datetime | keyword|country| 
1 | 1   | Mobitel |2012-11-05| JAM | RS |  
2 | 2   | Telekom |2013-04-25| ASTRO| RS |   
3 | 1   | Si.Mobil|2013-04-27| DOMACE| BA |    
4 | 4   | Telenor |2013-04-21| BIP | HR |  
5 | 7   | VIP  |2013-04-18| WIN | CZ |  
6 | 13   | VIP  |2014-05-21| DOMACE| RS |  
7 | 5   | VIP  |2014-06-04| WIN | HU | 

我需要總結的關鍵詞和國家,並總結再次關鍵字,國家和提供商分組的所有號碼組合的所有號碼全部在一個查詢中。

這裏是我試圖做到這一點:

SELECT (SELECT SUM(number),country, keyword 
     FROM daily_subscriptions 
     WHERE datetime >= '2016-02-01 23:59:59' 
     GROUP BY country, keyword) 
    num_of_all_subs, 
    SUM(number) as num_of_subs, 
    country, 
    keyword, 
    provider 
FROM daily_subscriptions 
WHERE datetime >= '2016-02-01 23:59:59' 
GROUP BY country, keyword, provider 

但此查詢引發錯誤:

#1241 - Operand should contain 1 column(s)

這是我希望得到:

id | num_of_all_subs|num_of_subs | provider| datetime | keyword|country| 
1 | 19    | 4   | Mobitel |2012-11-05| JAM | RS |  
2 | 12    | 5   |Telekom |2013-04-25| ASTRO| RS |   
3 | 18    | 1   |Si.Mobil |2013-04-27| DOMACE| BA |   
4 | 42    | 21   |Telenor |2013-04-21| BIP | HR |  
5 | 76    | 23   |VIP  |2013-04-18| WIN | CZ |  
6 | 13    | 3   |VIP  |2014-05-21| DOMACE| RS |  
7 | 53    | 11   |VIP  |2014-06-04| WIN | HU | 

num_of_all_subs這意味着讓所有數字的總和可以說JAM(關鍵字)和RS(國家)是19,但是每個Mob itel(提供者)從所有19箇中都是num_of_subs 4,因爲該國和關鍵字還有其他提供者(即使它們未在表模式中顯示)。

請幫我提取這些數據,因爲我卡住了。

+1

在sql-server或mysql之間進行選擇,但不是兩個 –

+0

好,現在顯示您的預期輸出,對於我而言,如果您想在同一行上創建總計和小計,或者希望將它們放在單獨的行中,則不清楚 –

+0

@ThomasG現在清楚了嗎? – Ognj3n

回答

1

您的子查詢num_of_all_subs(這是一個單一數字)只能返回一列,下一個問題只有一行。此外,此子查詢將在您進行分組之前進行評估,而您實際上首先對其進行分組並獲取num_of_subs,country,keywordprovider列,然後再向該第一個結果集添加另一列num_of_all_subs

您可以完全按照剛纔所描述的這樣做:先拿到分組子查詢(這裏稱爲details),然後用相關子查詢得到,在子查詢的每一行,通過查看該表(再次num_of_all_subs值),總結在具有相同providercountry所有行:

SELECT 
    (SELECT SUM(number) 
    FROM daily_subscriptions ds 
    WHERE datetime >= '2016-02-01 23:59:59' 
     and ds.country = details.country 
     and ds.keyword = details.keyword 
    ) as num_of_all_subs, 
    details.* 
from 
(select 
    SUM(number) as num_of_subs, 
    country, 
    keyword, 
    provider 
FROM daily_subscriptions 
WHERE datetime >= '2016-02-01 23:59:59' 
GROUP BY country, keyword, provider 
) as details; 

另一種方法是做計算兩組seperately,一個包括providerdetails),一個沒有(all_subs)。其中一個將包含num_of_subs,其中一個將包含num_of_all_subs。在可以結合(join)這兩個查詢時,他們具有相同的countrykeyword

SELECT 
    all_subs.num_of_all_subs, 
    details.* 
from 
(select 
    SUM(number) as num_of_subs, 
    country, 
    keyword, 
    provider 
FROM daily_subscriptions 
WHERE datetime >= '2016-02-01 23:59:59' 
GROUP BY country, keyword, provider 
) as details 
left join 
(SELECT 
    SUM(number) as num_of_all_subs, 
    country, 
    keyword 
FROM daily_subscriptions 
WHERE datetime >= '2016-02-01 23:59:59' 
GROUP BY country, keyword 
) as all_subs 
on all_subs.keyword = details.keyword and all_subs.country = details.country; 

在你的情況,你可以使用一個join代替left join,因爲在第一個子查詢中的每一行都會有在第二個子查詢中,雖然它通常是更安全的方式保留它。在理論上,MySQL可以以相同的方式執行這些查詢(對於不那麼複雜的查詢,它會實際上優化和處理,只要有可能和有用的依賴子查詢,比如連接),在當前的MySQL版本中,這很可能不會是情況和第二種選擇可能更快。無論如何,對於這兩個版本,(country, keyword, provider)上的複合索引都會創造奇蹟。

相關問題