2

假设我有一张桌子:

user_id    parent_id    lev1    lev2   lev3    lev4
1          0            0       0      0       0
2          1            1       0      0       0
3          1            1       0      0       0
4          2            2       1      0       0
5          4            4       2      1       0
6          4            4       2      1       0
7          5            5       4      2       1

基本上,这是为了跟踪父子层次结构,我想知道父母有多少孩子。下面是我想要的输出:

parent_id     children
1             5
2             4
3             0
4             3
5             1
6             0
7             0

我想计算组合的 lev1、lev2、lev3 和 lev4 字段,以计算这些字段中总共有多少个 ID。

我读到了 UNION ALL,但我似乎无法弄清楚它是如何运作的。我正在考虑一个带有自我加入的 UNION ALL?

4

2 回答 2

3

您需要LEFT JOIN针对每一levN列的子查询,它返回不同的级别,并为该列计数。然后他们都被加起来并加入到user_id.

SELECT
  DISTINCT
  user_id,
  /* COALESCE() is needed so NULLs don't ruin the calculation */
  COALESCE(l1count, 0) +
  COALESCE(l2count, 0) +
  COALESCE(l3count, 0) +
  COALESCE(l4count, 0) AS children
FROM
  yourtable
  /* a left join individually against each of the `levN` columns to get the count per value of each */
  LEFT JOIN (SELECT lev1, COUNT(*) AS l1count FROM yourtable GROUP BY lev1) l1 ON yourtable.user_id = l1.lev1
  LEFT JOIN (SELECT lev2, COUNT(*) AS l2count FROM yourtable GROUP BY lev2) l2 ON yourtable.user_id = l2.lev2
  LEFT JOIN (SELECT lev3, COUNT(*) AS l3count FROM yourtable GROUP BY lev3) l3 ON yourtable.user_id = l3.lev3
  LEFT JOIN (SELECT lev4, COUNT(*) AS l4count FROM yourtable GROUP BY lev4) l4 ON yourtable.user_id = l4.lev4

http://sqlfiddle.com/#!2/214a8/16

于 2013-02-06T14:03:29.657 回答
2

我可以让你部分到达那里,除了我没有显示任何计数为零的东西。(另外,正如@Raphaël Althaus 指出的那样,父母 1 在您的数据中计数为 6 而不是计数 5)。

sqlite> .schema
CREATE TABLE tmp (
user int,
parent int,
l1 int,
l2 int,
l3 int,
l4 int
);
sqlite> select * from tmp;
1,0,0,0,0,0
2,1,1,0,0,0
3,1,1,0,0,0
4,2,2,1,0,0
5,4,4,2,1,0
6,4,4,2,1,0
7,5,5,4,2,1
sqlite> select who,count(who) from
   ...>   (select l1 as who from tmp union all
   ...>    select l2 as who from tmp union all
   ...>    select l3 as who from tmp union all
   ...>    select l4 as who from tmp)
   ...> where who <> 0
   ...> group by who;
1,6
2,4
4,3
5,1
sqlite>
于 2013-02-06T17:01:17.077 回答