简体   繁体   中英

SUM acorrding to another column

I need to know if there is a possible way doing this with out subquery..

Here is my table structure:

id-name-father_id
1  joe    0
2  mark   0
3  muller 0
4  miki   2
5  timi   2
6  moses  2
7  david  1
8  momo   0
9  daniel 0
10 ermi   3

My table logic is

  • 0 means he is not a child of some one

  • 1+ mean that he is son of man in that row.

Note: if some one have a child, he still will have 0 in father id (it's mean there is not grand-fathers in my table)

My query is :

SELECT id, name, count(id=father_id) as sons
WHERE father_id = 0

What I want to get is a list of non-children (father_id=0) and sum the childrens it has. Is there a way to get the results without a subquery?

This should do it (MySQL):

SELECT `parents`.`id`, `parents`.`name`, COUNT(`children`.*) AS sons
FROM `people` AS parents
LEFT JOIN `people` AS children ON `parents`.`id` = `children`.`father_id`
WHERE `parents`.`father_id` = 0
GROUP BY `parents`.`id`

According to Gary we need to add name to GROUP BY in other SQL databases:

SELECT `parents`.`id`, `parents`.`name`, COUNT(`children`.*) AS sons
FROM `people` AS parents
LEFT JOIN `people` AS children ON `parents`.`id` = `children`.`father_id`
WHERE `parents`.`father_id` = 0
GROUP BY `parents`.`id`, `parents`.`name`

We are joing the table with itself here. So we join all parents with their children.

This will lead to a result like that:

parents.id  parents.name children.id  children.name
1           joe          7            david
2           mark         4            miki
2           mark         5            timi
2           mark         6            moses
3           muller       10           ermi
8           momo         -            - # left join allows this line
9           daniel       -            -

But now we have each parent several times. So we are GROUP'ing the whole thing over the parent's id, which will result in the following:

parents.id  parents.name COUNT(children.*)
1           joe          1
2           mark         3
3           muller       1
8           momo         0
9           daniel       0

You should be able to do it without any joins or sub-queries as follows:

select case father_id when 0 then id else father_id end id,
       max(case father_id when 0 then name end)     name,
       sum(sign(father_id))                         sons
from table
group by case father_id when 0 then id else father_id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM