PostgreSQL Percentage

3

I can not perform the percentage of this query.

You should take the sum of the "value_convenio" of each municipality and divide by the sum total of the "value_convenio" :

<h3>Entrada SQL SEM CALCULO DE PORCENTAGEM</h3>
SELECT
    nome_municipio,
        SUM(valor_convenio)<br/>
FROM
    paraiba.vigente<br/>
WHERE 
    convenente LIKE '%(MUNICIPAL)%'<br/>
GROUP BY
    nome_municipio<br/>
ORDER BY
    "Total Conveniado (R$)" DESC;<br/>


<h3>Exemplo de Saída ATUAL:</h3>------------------------------------------------------
<br/>|JOAO PESSOA.......|R$272.789.654,75|
<br/>|CAMPINA GRANDE|R$182.080.728,84|
<br/>|PIANCO...................|..R$35.392.580,61|
<br/>|SUME......................|..R$34.040.127,05|
<br/>|CABEDELO.............|..R$30.652.583,47|
<br/>|SOUSA....................|..R$22.075.733,70|
<br/>|PATOS.....................|..R$20.061.310,59|
<br/>-------------------------------------------------------

<h3>Exemplo de Saída QUE PRECISO:</h3>--------------------------------------------------------------
<br/>|JOAO PESSOA.......|R$272.789.654,75|..22%
<br/>|CAMPINA GRANDE|R$182.080.728,84|..15%
<br/>|PIANCO...................|..R$35.392.580,61|....3%
<br/>|SUME......................|..R$34.040.127,05|....3%
<br/>|CABEDELO.............|..R$30.652.583,47|....2%
<br/>|SOUSA....................|..R$22.075.733,70|....2%
<br/>|PATOS.....................|..R$20.061.310,59|....1%
<br/>--------------------------------------------------------------

At the end of I export to csv file separated by ";" staying in this pattern:

JOAO PESSOA;272.789.655;22%<br/>
CAMPINA GRANDE;182.080.729;15%<br/>
PIANCO;35.392.581;3%<br/>
SUME;34.040.127;3%<br/>
CABEDELO;30.652.583;2%<br/>
SOUSA;22.075.734;2%<br/>
PATOS;20.061.311;2%<br/>
    
asked by anonymous 09.04.2018 / 20:48

1 answer

1

First, you need a query that returns the sum of all values in the valor_convenio column. The query would then be simple:

select
    sum (valor_convenio) as total
from paraiba.vigente
WHERE
    convenente LIKE '%(MUNICIPAL)%'

In addition, you already have the query that adds the valor_convenio grouped by municipality (I did some alias modifications because the query did not execute the way you wrote it):

SELECT
    nome_municipio,
    SUM(valor_convenio) as total
FROM paraiba.vigente
WHERE
    convenente LIKE '%(MUNICIPAL)%'
GROUP BY nome_municipio
ORDER BY total DESC;

What is needed now is to simply merge the queries so that you get the percentage value. For this, a join can be used. It basically serves to merge complex query results. So adding the junction would look something like:

SELECT
    nome_municipio,
    SUM(valor_convenio),
    SUM(valor_convenio) / total.total AS total
FROM paraiba.vigente, (
    select sum (valor_convenio) as total 
    from paraiba.vigente 
    WHERE convenente LIKE '%(MUNICIPAL)%'
) total 
WHERE convenente LIKE '%(MUNICIPAL)%' 
GROUP BY nome_municipio 
ORDER BY total DESC;

If you run the above query, you will encounter the following error:

  

ERROR: column "total.total" must appear in the GROUP BY clause or be used in an aggregate function   LINE 1: ... nicipio, SUM (value_convenio), SUM (value_convenio) / total.tota ...

The problem is that there is a SUM grouping function with 2 different query results, and this needs to be added in a group by clause so that the information can be aggregated by the function. Since the value of the total sum of the valor_convenio column is unique for all counties, you can add it to the group by class with no impact on the final result. So you would have something like:

SELECT 
    nome_municipio, 
    SUM(valor_convenio),
    SUM(valor_convenio) / total.total AS total 
FROM paraiba.vigente, (
    select sum (valor_convenio) as total 
    from paraiba.vigente
    WHERE convenente LIKE '%(MUNICIPAL)%'
) total 
WHERE convenente LIKE '%(MUNICIPAL)%'
GROUP BY nome_municipio, total.total 
ORDER BY total DESC;

To adjust the query by adding a percentage format, you can do something like the example below, using the round rounding function and the string concatenation operator || :

SELECT 
    nome_municipio,
    SUM(valor_convenio),
    round((SUM(valor_convenio)/total.total)*100, 2) || '%' AS total
FROM paraiba.vigente, (
    select sum (valor_convenio) as total  
    from paraiba.vigente 
    WHERE convenente LIKE '%(MUNICIPAL)%'
) total
WHERE convenente LIKE '%(MUNICIPAL)%'
GROUP BY nome_municipio, total.total
ORDER BY total DESC;

Tip: Whenever you have complex queries to build, construct each piece separately and then think about the logic of joining them together. This makes it much easier to solve such problems.

    
09.04.2018 / 23:26