sqlpostgresqlpgadminpostgresql-15

Calculating percentage in a table is giving correct and wrong answers with the same query


I have a table with year, area codes and each area code has 5 categories of age groups with people count as below.

year areacode agegroup persons
2021 code 1 20-29 5
2021 code 2 30-39 11
2022 code 1 20-29 7
2022 code 2 30-39 5
2020 code 1 20-29 0
2020 code 2 30-39 6
2019 code 1 20-29 0
2019 code 2 30-39 0

I need to calculate percentage of persons for each group out of total persons per areacode, the result I need is:

fid year areacode agegroup persons percent
1 2021 code 1 20-29 5 31.3%
2 2021 code 2 30-39 11 68.8%
3 2022 code 1 20-29 7 58.3%
4 2022 code 2 30-39 5 41.7%
5 2020 code 1 20-29 0 0.0%
6 2020 code 2 30-39 6 100.0%
7 2019 code 1 20-29 0 0.0%
8 2019 code 2 30-39 0 0.0%

But the result I'm getting is bizarre, it is partially giving correct answers and also wrong answers. See below result.

fid year areacode agegroup persons total_sum test percent
1 2021 code 1 20-29 5 16 1 0.0%
2 2021 code 2 30-39 11 16 1 0.0%
3 2022 code 1 20-29 7 12 1 0.0%
4 2022 code 2 30-39 5 12 1 0.0%
5 2020 code 1 20-29 0 6 1 0.0%
6 2020 code 2 30-39 6 6 1 100.0%
7 2019 code 1 20-29 0 0 0 0.0%
8 2019 code 2 30-39 0 0 0 0.0%

Any percentage that is other than 0 or 100, is resulting in 0% To test the total_sum column, I added the test column where the total is 0 give 0, else 1. And that works perfectly fine.

I'm using the following code:

select 
    table.fid, 
    table.year, 
    table.areacode,
    table.agegroup,
    table.persons,
    totals.total_sum,
    case
        when totals.total_sum = 0 then 0
        else 1
    end as test,
    case
        when totals.total_sum = 0 then 0
        else ((table.persons)/totals.total_sum)*100.0
    end as percent
from abc.table
join (
    select
        table.year,
        table.areacode,
        sum(table.persons) as total_sum
    from abc.table
    group by table.areacode, table.year) as totals
on table.areacode = totals.areacode and table.year=totals.year
group by table.areacode, table.fid, table.year, table.agegroup, totals.total_sum
order by totals.total_sum

I tried finding anything related to this kind of error, but unfortunately, I didn't find anything (Maybe, I'm using the wrong keywords).

Does anyone know why is this happening? I'd really appreciate it.


Solution

  • Integer division discards remainders. You need to change one integer into a float before the division is done. Just move the constant upfront and inside the parentheses

    (100.0*table.persons/totals.total_sum)