4

我有一个看起来像这样的表:

Categories:
cId | Name                    | Parent
----+-------------------------+-------
1   | Parent One              | NULL
2   | Child of 1st Parent     | 1
3   | Parent Two              | NULL
4   | Child of 1st Parent     | 1
5   | Child of 2nd Parent     | 2

该表不代表层次结构:每个项目要么是子项,要么是父项,但不能两者兼而有之。

一张这样的桌子:

Posts:
pId | Name                    | cID
----+-------------------------+-------
1   | Post 1                  | 1
2   | Post 2                  | 2
3   | Post 3                  | 2
4   | Post 4                  | 3

我想对它运行一个查询,返回这个:

cId | Count  
---+---------
1   | 3
2   | 2
3   | 1
4   | 0
5   | 0

Count 是与该类别相关的帖子数。

应返回所有类别。

父类别应该有类别 + 子类别总和的计数。(这是我遇到的问题之一)

子类别应具有类别总和。

我该怎么做?

4

2 回答 2

3

从您的预期结果来看,您似乎不关心孙子及下级,在这种情况下,这应该可行。为了获得正确的父计数,我正在检查 Parent IS NULL 或 Count(children) > 0,在这种情况下,我加 1:

SELECT c.cId, CASE WHEN C.Parent IS NULL OR COUNT(C2.cId) > 0 THEN 1 ELSE 0 END + 
    COUNT(C2.cId) TotalCount
FROM Categories C
    LEFT JOIN Categories C2 on c.cId = c2.Parent
GROUP BY c.cId

这是一些示例小提琴:http ://www.sqlfiddle.com/#!2/b899f/1

结果:

CID  TOTALCOUNT
1    3
2    2
3    1
4    0
5    0

- -编辑 - -

通过阅读您的评论,您似乎想要这样的东西:

SELECT c.cId, 
    COUNT(DISTINCT P.pId) + COUNT(DISTINCT P2.pId) TotalCount
FROM Categories C
   LEFT JOIN Posts P ON C.CId = P.CId
    LEFT JOIN Categories C2 on c.cId = c2.Parent
   LEFT JOIN Posts P2 ON C2.CId = P2.CId
GROUP BY c.cId

http://www.sqlfiddle.com/#!2/eb0d2/3

于 2013-02-20T16:10:29.970 回答
0

这是一般提示。我不知道 MySQL 中是否提供分析函数和分区,但您可以按类别对输出进行分区,然后在类别中进行计数和汇总。做一些关于分析函数和按子句划分的研究。我的意思的一般示例 - 输出由 deptno 分区并排序。此外,在分区内确定的最大雇用日期 - 在您的情况下用计数、总和等替换最大值:

SELECT * FROM 
(  
SELECT deptno
     , empno
     , ename
     , sal
     , RANK() OVER (PARTITION BY deptno ORDER BY sal desc) rnk 
     , ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY sal desc) rno 
     , MAX(hiredate) OVER (PARTITION BY deptno ORDER BY deptno) max_hire_date
 FROM emp_test
ORDER BY deptno
)
--WHERE rnk = 1
ORDER BY deptno, sal desc
/

DEPTNO    EMPNO    ENAME    SAL    RNK    RNO    MAX_HIRE_DATE
--------------------------------------------------------------------
10        7839    KING      5000    1      1    1/23/1982
10        7782    CLARK     2450    2      2    1/23/1982
10        7934    MILLER    1300    3      3    1/23/1982
20        7788    SCOTT     3000    1      1    1/28/2013
20        7902    FORD      3000    1      2    1/28/2013
20        7566    JONES     2975    3      3    1/28/2013
于 2013-02-20T16:21:28.477 回答