Estou convertendo um antigo sistema baseado em MS-Access para PostgreSQL. No Access, os campos que foram criados em SELECTs podem ser usados como partes de equações para campos posteriores, assim:
SELECT
samples.id,
samples.wet_weight / samples.dry_weight - 1 AS percent_water,
100 * percent_water AS percent_water_100
FROM samples;
Quando faço isso no PostgreSQL, o Postgres lança um erro:
ERRO: a coluna "percent_water" não existe.
Veja como posso contornar isso, selecionando uma subseleção:
SELECT
s1.id,
s1.percent_water,
100 * s1.percent_water AS percent_water_100
FROM (
SELECT
samples.id,
samples.wet_weight / samples.dry_weight - 1 AS percent_water
FROM samples
) s1;
Existe algum tipo de atalho como no primeiro bloco de código para contornar o aninhamento complicado? Eu também poderia dizer 100 * (samples.wet_weight / samples.dry_weight - 1) AS percent_water_100
, mas este é apenas um pequeno exemplo do que é um sistema muito maior de matemática acontecendo no meu código, com dezenas de bits mais complexos de matemática empilhados uns sobre os outros. Prefiro fazer o mais limpo possível sem me repetir.
Às vezes é inconveniente, mas é o comportamento padrão do SQL e evita ambiguidades. As expressões na
SELECT
lista não podem fazer referência a nomes de colunas de saída da mesmaSELECT
lista, apenas nomes de colunas de entrada de relações naFROM
cláusula.Existem opções de sintaxe mais curtas:
E você pode usar uma
LATERAL
junção no Postgres 9.3+:NULLIF()
defende contra erros de divisão por zero.Eu bati em algo assim migrando uma consulta Netezza com mais de 500 linhas (também conhecida como Postgres modificado) para o SQL Server. No Netezza, o alias de coluna computado tinha permissão para ser usado como um valor em referências de recebimento de dados.
Meu trabalho foi usar CROSS APPLY com uma subconsulta correlacionada. A beleza disso é que as inúmeras referências ao alias da coluna na consulta original não precisaram ser alteradas.
Usando a consulta do OP, o
CROSS APPLY
método seria algo como: