Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

431
Visualizações
Postgres query : using previous dynamically created colum value in next

I'm trying to implement what I have in code as a postgres query. The following example isn't exactly what we're trying to do but I hope it shows how I'm trying to use the value from a previously calculated row in the next.

A sample table to help me demonstrate what I'm trying to do :

test=# select * from test ;
 id | field1 | field2 | field3 | score
----+--------+--------+--------+-------
  1 |      1 |      3 |      2 |  1.25
  2 |      1 |     -1 |      1 |
  3 |      2 |      1 |      5 |
  4 |      3 |     -2 |      4 |

Here's the query in progress:

select id,
    coalesce (
            score,
            case when lag_field3 = 2 then 0.25*(3*field1+field2) end
    ) as new_score
from (
    select id, field1, field2, field3, score,
    lag (field3)  over (order by id) as lag_field3
    from test
) inner1 ;

Which returns what I want so far ...

 id | new_score
----+-----------
  1 |      1.25
  2 |       0.5
  3 |
  4 |

The next iteration of the query:

select id,
    coalesce (
            score,
            case when lag_field3 = 2 then 0.25*(3*field1+field2) end,
            case when field1 = 2 then 0.75 * lag (new_score) end
    ) as new_score
from (
select id, field1, field2, field3, score,
    lag (field3)  over (order by id) as lag_field3
from test
) inner1 ;

The difference is this :

case when field1 = 2 then 0.75 * lag (new_score) end

I know and understand why this won't work.

I've aliased the calculated field as new_score and when field1 = 2, I want 0.75 * the previous rows new_score value. I understand that new_score is an alias and can't be used.

Is there some way I can accomplish this? I could try to copy that expression, wrap a lag around it, alias that as something else and try to work with that but that would get very messy.

Any ideas?

Many thanks.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Postgres lets you use windows in CASE statements. Probably you were missing the OVER (ORDER BY id) part. You can also define different windows but you can't use windows in conjunction with GROUP BY. Also, it won't let you use annidate windows, so you have to write down some subqueries or CTEs.

Here's the query:

SELECT id, COALESCE(tmp_score,
                    CASE 
                        WHEN field1 = 2 
                            THEN 0.75 * LAG(tmp_score) OVER (ORDER BY id) 
                            -- missing ELSE statement here
                    END
           ) AS new_score
FROM (
    SELECT id, field1,
        COALESCE (
                score,
                CASE 
                    WHEN LAG(field3) OVER (ORDER BY id) = 2 
                    THEN 0.25*(3*field1+field2) 
                END
        ) AS tmp_score
    FROM test
) inner1

The code to create and populate the table:

CREATE TABLE test(
    id int,
    field1 int,
    field2 int,
    field3 int,
    score numeric
);

INSERT INTO test VALUES
(1, 1, 3, 2, 1.25),
(2, 1, -1, 1, NULL),
(3, 2, 1, 5, NULL),
(4, 3, -2, 4, NULL);

The query returns this output:

 id | new_score 
----+-----------
  1 |      1.25
  2 |      0.50
  3 |    0.3750
  4 |          
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda