使行有条件的快速修复是向该查询'Others'
添加一个简单的子句。HAVING
HAVING COUNT(c.id) > 0
(如果表中没有其他行contents
,则将COUNT(c.id)
为零。)
这只回答了一半的问题,即如何使该行的返回有条件。
问题的后半部分涉及更多一点。
要在一个查询中获取整个结果集,您可以执行以下操作
(这还没有测试;只检查了桌面。我不确定postgresql是否接受内联视图中的LIMIT子句......如果不是,我们需要实现不同的机制来限制行数回来。
SELECT IFNULL(t.name,'Others') AS name
, t.catid AS catid
, COUNT(o.id) AS data
FROM contents o
LEFT
JOIN category oa
ON oa.id = o.category_id
LEFT
JOIN ( SELECT COALESCE(ca.name,'Unknown') AS name
, ca.id AS catid
, COUNT(c.id) AS data
FROM contents c
LEFT
JOIN category ca
ON ca.id = c.categoryid
GROUP
BY COALESCE(ca.name,'Unknown')
, ca.id
ORDER
BY COUNT(c.id) DESC
, ca.id DESC
LIMIT 7
) t
ON ( t.catid = oa.id OR (t.catid IS NULL AND oa.id IS NULL))
GROUP
BY ( t.catid = oa.id OR (t.catid IS NULL AND oa.id IS NULL))
, t.catid
ORDER
BY COUNT(o.id) DESC
, ( t.catid = oa.id OR (t.catid IS NULL AND oa.id IS NULL)) DESC
, t.catid DESC
LIMIT 7
内联视图t
基本上得到与第一个查询相同的结果,来自类别表的(最多)7 个id
值的列表,或来自类别表的 6 个id
值和一个 NULL。
外部查询基本上做同样的事情,加入content
with category
,但也会检查是否有匹配的行 from t
。因为t
可能会返回 NULL,所以我们有一个稍微复杂的比较,我们希望 NULL 值与 NULL 值匹配。(MySQL 方便地为此提供了速记运算符,即 null-safe 比较运算符<=>
,但我认为 postgresql 中没有,因此我们必须以不同的方式表达。
a = b OR (a IS NULL AND b IS NULL)
下一点是让 GROUP BY 工作,我们希望按内联视图返回的 7 个值进行分组t
,或者,如果没有匹配的值 from t
,则将“其他”行组合在一起。我们可以通过在 GROUP BY 子句中使用布尔表达式来实现这一点。
我们基本上是在说“按'如果有来自 t' 的匹配行进行分组”(真或假),然后按来自 't' 的行进行分组。获取一个计数,然后按计数降序排列。
这未经测试,仅经过桌面检查。