2012-10-02 53 views
23

餘數從多個列中的值是這樣的:計數與組多個列通過在一個查詢

SELECT COUNT(column1),column1 FROM table GROUP BY column1 
SELECT COUNT(column2),column2 FROM table GROUP BY column2 
SELECT COUNT(column3),column3 FROM table GROUP BY column3 

這將返回例如用於COLUMN1陣列(attR1位=> 2000,attR2位=> 3000 ...)(每列都有特定的值和少量值)。問題是我的應用程序中的「table」可能是一個帶有一些連接和where子句的查詢,可能需要0.1秒。通過重新計算每次計算「表格」,這是不必要的。有什麼辦法可以用一個查詢來獲得我想要的結果,或者「緩存」生成表的查詢嗎?否則,我認爲非規範化將是唯一的解決方案。我想要與上述查詢相同的結果。我正在使用mysql-myisam。

+0

哪有數量同一張表上的每列的行不同? – Kermit

+0

您可以將查詢結果存儲在臨時表中嗎? – Beth

+0

可能重複[如何獲得多個計數與一個SQL查詢?](http://stackoverflow.com/questions/12789396/how-to-get-multiple-counts-with-one-sql-query) – kdauria

回答

34

很難知道如何幫助你不理解您的數據的上下文/結構,但我相信這可以幫助你:

SELECT 
    SUM(CASE WHEN column1 IS NOT NULL THEN 1 ELSE 0 END) AS column1_count 
    ,SUM(CASE WHEN column2 IS NOT NULL THEN 1 ELSE 0 END) AS column2_count 
    ,SUM(CASE WHEN column3 IS NOT NULL THEN 1 ELSE 0 END) AS column3_count 
FROM table 
+0

這是一個非常有用的查詢,尤其是當您需要參與記錄的計數時。例如,當我需要向我發送郵件的用戶數量時,我會使用您的查詢的稍微修改版本。 'SELECT DateSent,SUM(CASE WHEN TotalMessageCount> 1 THEN 1 ELSE 0 END)UserCount' – Vicky1729

6

一種解決辦法是把它包在一個子查詢

SELECT * 
FROM 
(
    SELECT COUNT(column1),column1 FROM table GROUP BY column1 
    UNION ALL 
    SELECT COUNT(column2),column2 FROM table GROUP BY column2 
    UNION ALL 
    SELECT COUNT(column3),column3 FROM table GROUP BY column3 
) s 
+0

請問這不是多次「計算」表格? –

+0

無論如何,它必須計算三次。您不能按三個不同的字段進行分組,並希望系統不必爲每個不同的分組重新計算。在它的臉上,這是不可能的。將它們放入單個查詢可能會允許系統重新使用該視圖,但是如果沒有,我會調查索引或失敗的臨時表。 –

+0

我有需要計數的所有列中的索引。此查詢未優化,因爲表必須是子查詢(SELECT column1 FROM table JOIN table2 ON ... WHERE ....),並且它會再次計算子查詢。我想反規範化,所以我沒有加入..創建臨時表也是一個小時間.. – user666

1

你沒有說你正在使用的數據庫服務器,但如果臨時表可他們可能是最好的辦法。

// table is a temp table 
select ... into #table .... 
SELECT COUNT(column1),column1 FROM #table GROUP BY column1 
SELECT COUNT(column2),column2 FROM #table GROUP BY column2 
SELECT COUNT(column3),column3 FROM #table GROUP BY column3 
// drop may not be required 
drop table #table 
+0

是的,我可以創建臨時表,(MySQL社區服務器),但我不認爲它會有一個偉大的提高性能,因爲創建臨時表需要約1秒。我所做的查詢需要0.1-0.2秒,大約1秒左右。 (您是不是指CREATE TEMPORARY TABLE AS {query}?) – user666

+0

我相信Sybase數據庫服務器上面的語法(以#開頭的表名)會創建一個臨時表,它通常存儲在內存中。這似乎並不適合你,導致昂貴的磁盤I/O。使用內存表時,如果生成的大小不是太大,臨時表應該有幫助 –

2
select tab1.name, 
count(distinct tab2.id) as tab2_record_count 
count(distinct tab3.id) as tab3_record_count 
count(distinct tab4.id) as tab4_record_count 
from tab1 
left join tab2 on tab2.tab1_id = tab1.id 
left join tab3 on tab3.tab1_id = tab1.id 
left join tab4 on tab4.tab1_id = tab1.id 
0
SELECT SUM(Output.count),Output.attr 
FROM 
(
    SELECT COUNT(column1 ) AS count,column1 AS attr FROM tab1 GROUP BY column1 
    UNION ALL 
    SELECT COUNT(column2) AS count,column2 AS attr FROM tab1 GROUP BY column2 
    UNION ALL 
    SELECT COUNT(column3) AS count,column3 AS attr FROM tab1 GROUP BY column3) AS Output 

    GROUP BY attr