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 with self JOINを考えていますか?

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ëlAlthausが指摘したように、親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 に答える