2008-11-11 118 views
2

通常,您需要顯示數據庫項目的列表以及有關每個項目的特定總數。例如,當您在堆棧溢出中鍵入標題文本時,將出現相關問題列表。該列表顯示了相關條目的標題以及每個標題的單個合計答覆數量。查詢:計算每個項目的多個總計數

我有一個類似的問題,但需要多個聚合。我想在任何的3種格式,具體取決於用戶選擇顯示的項目清單:

  • 我的項目的名稱(15總,13由我擁有)
  • 我的項目的名稱(15個)
  • (我擁有的13)
  • 我的項目的名稱

我的數據庫是:

  • 項目:的itemId,ITEMNAME, OWNERID
  • :CATID,catName
  • 地圖:的azazaz,的itemId,CATID

下面的查詢獲取:類別名稱,每個類別

SELECT 
    categories.catName, 
    COUNT(map.itemId) AS item_count 
FROM categories 
LEFT JOIN map 
    ON categories.catId = map.catId 
GROUP BY categories.catName 

項ID的數這一個得到:類別名稱,每個類別的這個owner_id的物品id的數量只有

SELECT categories.catName, 
COUNT(map.itemId) AS owner_item_count 
FROM categories 
LEFT JOIN map 
    ON categories.catId = map.catId 
LEFT JOIN items 
    ON items.itemId = map.itemId 
WHERE owner = @ownerId 
GROUP BY categories.catId 

但是我如何在單個查詢中同時獲取它們? I.e .:類別名稱,每個類別的物品ID計數,僅針對該owner_id的每個類別的物品ID計數

獎勵。我可以選擇只檢索其中任何一個的catId數!= 0。在試圖「WHERE ITEM_COUNT <> 0」,我得到:

MySQL said: Documentation 
#1054 - Unknown column 'rid_count' in 'where clause' 

回答

5

這裏有一個竅門:計算被稱爲是1或0值的SUM()等價於值爲1的行的COUNT() 。你知道一個布爾比較返回1或0(或NULL)。

SELECT c.catname, COUNT(m.catid) AS item_count, 
    SUM(i.ownerid = @ownerid) AS owner_item_count 
FROM categories c 
    LEFT JOIN map m USING (catid) 
    LEFT JOIN items i USING (itemid) 
GROUP BY c.catid; 

至於獎金問題,你可以簡單地做一個內部聯接,而不是外部連接,這意味着僅類別與至少一排map將返回。

SELECT c.catname, COUNT(m.catid) AS item_count, 
    SUM(i.ownerid = @ownerid) AS owner_item_count 
FROM categories c 
    INNER JOIN map m USING (catid) 
    INNER JOIN items i USING (itemid) 
GROUP BY c.catid; 

這裏的另一種解決方案,這是效率不高,但我會告訴它來解釋爲什麼你得到了錯誤:

SELECT c.catname, COUNT(m.catid) AS item_count, 
    SUM(i.ownerid = @ownerid) AS owner_item_count 
FROM categories c 
    LEFT JOIN map m USING (catid) 
    LEFT JOIN items i USING (itemid) 
GROUP BY c.catid 
HAVING item_count > 0; 

不能在WHERE子句中使用列別名,因爲在選擇列表中的表達式之前評估WHERE子句中的表達式。換句話說,與選擇列表表達式相關的值尚不可用。

您可以在GROUP BYHAVINGORDER BY子句中使用列別名。這些子句在選擇列表中的所有表達式都被評估後運行。

4

你可以偷偷CASE語句的SUM()內:

SELECT categories.catName, 
    COUNT(map.itemId) AS item_count, 
    SUM(CASE WHEN owner= @ownerid THEN 1 ELSE 0 END) AS owner_item_count 
FROM categories 
LEFT JOIN map ON categories.catId = map.catId 
LEFT JOIN items ON items.itemId = map.itemId 
GROUP BY categories.catId 
HAVING COUNT(map.itemId) > 0 
2
SELECT categories.catName, 
    COUNT(map.itemId) AS item_count, 
    COUNT(items.itemId) AS owner_item_count 
FROM categories 
INNER JOIN map 
    ON categories.catId = map.catId 
LEFT JOIN items 
    ON items.itemId = map.itemId 
    AND items.owner = @ownerId 
GROUP BY categories.catId 

請注意,您可以在owner_item_count使用HAVING條款,但內部加入照顧ITEM_COUNT的爲您服務。