通常,您需要显示数据库项目列表以及每个项目的某些聚合数字。例如,在Stack Overflow上键入标题文本时,将显示“相关问题”列表。该列表显示了相关条目的标题以及每个标题的单个汇总回复数量。
我有类似的问题,但需要多个聚合。我想根据用户选项显示3种格式的项目列表:
我的数据库是:
以下查询获取:类别名称,每个类别的项目ID数量
SELECT
categories.catName,
COUNT(map.itemId) AS item_count
FROM categories
LEFT JOIN map
ON categories.catId = map.catId
GROUP BY categories.catName
这个获得:类别名称,此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'
答案 0 :(得分: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
子句中的表达式是在select-list中的表达式之前计算的。换句话说,与select-list表达式关联的值尚不可用。
您可以在GROUP BY
,HAVING
和ORDER BY
子句中使用列别名。在评估了select-list中的所有表达式之后运行这些子句。
答案 1 :(得分:4)
您可以在SUM()中隐藏CASE语句:
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 :(得分: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
请注意,您可以在HAVING
上使用owner_item_count
子句,但内部联接会为您处理item_count。