Aggregation error only in postgresql 9.4

Asked

Viewed 53 times

0

I am having the following error when using the postgresql database in production (version 9.46), in development the error does not appear (9.6). PG::Groupingerror: ERROR: column "sectors.name" should appear in the GROUP BY clause or be used in an aggregation function. follows the sql query:

    SELECT materiais.id material_id, insumos.nome material_nome, 
    apresentacoes.id apresentacao_id, apresentacoes.apresentacao 
    apresentacao_apresentacao, estoques.setor_id, estoques.setor_nome, 
    estoques.total total, estoques.valor_total valor_total FROM materiais
    INNER JOIN insumos ON insumos.id = materiais.insumo_id
    LEFT JOIN apresentacoes ON apresentacoes.material_id = materiais.id
    LEFT JOIN (
        SELECT setores.nome setor_nome, 
                estoques.setor_id setor_id, 
                estoques.material_id, 
                estoques.apresentacao_id, 
                SUM(lotes.quantidade) total, 
                SUM(lotes.quantidade*lotes.valor_unitario_cents) valor_total
        FROM estoques 
        INNER JOIN setores ON setores.id = estoques.setor_id 
        INNER JOIN lotes ON lotes.estoque_id = estoques.id
        GROUP BY (setores.nome, 
                 estoques.setor_id, 
                 estoques.material_id,
                 estoques.apresentacao_id)
    ) 
    estoques ON estoques.material_id = materiais.id AND apresentacoes.id = 
    estoques.apresentacao_id 
    where materiais.setor_type = 'Farmacia' 
    ORDER BY insumos.nome DESC, apresentacoes.id

Note: I’ve tried using an aggregation function in select by: array_agg(sectors.name)[1] setor_name. But the error goes to the next column of select, causing me to add all the columns. Does anyone have another solution without being so gambiarra? and. and

  • You have a table estoques and is also assigning the nickname estoques to your sub-select, you have already tried to assign a different nickname?

  • Note that it was introduced in version 9.6: "Ignore GROUP BY Columns that are functionally dependent on other Columns".

  • I changed the alias name to full stoques_and the error persists. Maybe it is the version of the same postegres, in case n appears another option I will try to update the version of the production bank.

2 answers

0

Make sure this is it:

SELECT  materiais.id material_id, insumos.nome material_nome, 
            apresentacoes.id apresentacao_id, apresentacoes.apresentacao 
            apresentacao_apresentacao, estoques_total.setor_id, estoques_total.setor_nome, 
            estoques_total.total total, estoques_total.valor_total valor_total 
FROM materiais INNER JOIN insumos ON insumos.id = materiais.insumo_id
    LEFT JOIN apresentacoes ON apresentacoes.material_id = materiais.id
    LEFT JOIN (
        SELECT  setores.nome setor_nome, 
                estoques.setor_id setor_id, 
                estoques.material_id, 
                estoques.apresentacao_id, 
                SUM(lotes.quantidade) total, 
                SUM(lotes.quantidade*lotes.valor_unitario_cents) valor_total
        FROM estoques 
        INNER JOIN setores ON setores.id = estoques.setor_id 
        INNER JOIN lotes ON lotes.estoque_id = estoques.id
        GROUP BY setores.nome, 
                 estoques.setor_id, 
                 estoques.material_id,
                 estoques.apresentacao_id
    ) AS estoques_total ON estoques_total.material_id = materiais.id AND apresentacoes.id = estoques_total.apresentacao_id 
WHERE materiais.setor_type = 'Farmacia' 
ORDER BY insumos.nome DESC, apresentacoes.id;`insira o código aqui`

0


Strange this error, the SQL command seems correct. Try to put the Sub Select in a WITH:

WITH query_estoques AS 
(
   SELECT setores.nome setor_nome, 
          estoques.setor_id setor_id, 
          estoques.material_id, 
          estoques.apresentacao_id, 
          SUM(lotes.quantidade) total, 
          SUM(lotes.quantidade*lotes.valor_unitario_cents) valor_total
   FROM estoques 
   INNER JOIN setores ON setores.id = estoques.setor_id 
   INNER JOIN lotes ON lotes.estoque_id = estoques.id
   GROUP BY (setores.nome, 
           estoques.setor_id, 
           estoques.material_id,
           estoques.apresentacao_id)
)

 SELECT materiais.id material_id, insumos.nome material_nome, 
    apresentacoes.id apresentacao_id, apresentacoes.apresentacao 
    apresentacao_apresentacao, query_estoques.setor_id, query_estoques.setor_nome, 
    query_estoques.total total, query_estoques.valor_total valor_total FROM materiais
 INNER JOIN insumos ON insumos.id = materiais.insumo_id
 LEFT JOIN apresentacoes ON apresentacoes.material_id = materiais.id
 LEFT JOIN query_estoques ON query_estoques.material_id = materiais.id AND apresentacoes.id = query_estoques.apresentacao_id 
 where materiais.setor_type = 'Farmacia' 
 ORDER BY insumos.nome DESC, apresentacoes.id

Or try to use the number corresponding to the order of the columns in the GROUP BY instead of using the names:

SELECT setores.nome setor_nome, 
          estoques.setor_id setor_id, 
          estoques.material_id, 
          estoques.apresentacao_id, 
          SUM(lotes.quantidade) total, 
          SUM(lotes.quantidade*lotes.valor_unitario_cents) valor_total
   FROM estoques 
   INNER JOIN setores ON setores.id = estoques.setor_id 
   INNER JOIN lotes ON lotes.estoque_id = estoques.id
   GROUP BY 1, 2, 3, 4
  • Using the corresponding number the order of the columns solved the problem, thank you very much :D.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.