Tenho a seguinte tabela no Postgres:
CREATE TABLE avg (
user_id INT,
numer DOUBLE PRECISION,
denom DOUBLE PRECISION,
frac DOUBLE PRECISION
);
Quero realizar o seguinte e estou tendo dificuldade em colocar isso em uma consulta. Basicamente quero poder atualizar algumas médias atomicamente, atualizando separadamente o numerador e o denominador, e depois calcular e atualizar a média frac
na mesma operação, com base nos novos valores:
- Dados os parâmetros
a
eb
, quero encontrar a linha para um determinadouser_id
, então quero fazernumer += a
edenom += b
calcularfrac = numer / denom
a partir dos novos valores denumer
e edenom
, em seguida, atualizar os valores denumer
,denom
efrac
nesta linha. - Porém, se não houver nenhuma linha para o solicitado
user_id
, ou se houver uma linha, mas os valores denumer
edenom
forem nulos, então quero assumir que o valor dessas somas é zero, ou seja, uma nova linha deve ser inserida em a tabela, ou uma operação de atualização deve ser executada se houver uma linha, mas os valores forem nulos, com o resultado sendo definidonumer = a
,denom = b
efrac = a / b
para ouser_id
. - Quero garantir que tudo isso aconteça atomicamente.
Pode haver vários numeradores e denominadores em uma determinada tabela, daí a necessidade de ser capaz de inserir (se a linha não existir) ou atualizar (se a linha existir, mas os valores iniciais de um par numerador/denominador específico forem nulo).
A melhor prática é não armazenar dados redundantes em um banco de dados. Minha solução seria
Então você pode realizar a operação desejada da seguinte maneira:
Se você insiste em usar uma coluna de tabela redundante, use uma coluna gerada que seja atualizada automaticamente: