J'ai du mal à utiliser une colonne calculée en postgres. Un code similaire qui fonctionne en SQL est donné ci-dessous, est-il possible de le recréer dans PostgreSQL
?
select cost_1, quantity_1, cost_2, quantity_2,
(cost_1 * quantity_1) as total_1,
(cost_2 * quantity_2) as total_2,
(calculated total_1 + calculated total_2) as total_3
from data;
Dans PostgreSQL
, un code similaire renvoie l'erreur qui:
les colonnes total_1 et total_2 n'existent pas.
Vous devez encapsuler l'instruction SELECT dans une table dérivée afin de pouvoir accéder à l'alias de colonne:
select cost1,
quantity_1,
cost_2,
quantity_2
total_1 + total_2 as total_3
from (
select cost_1,
quantity_1,
cost_2,
quantity_2,
(cost_1 * quantity_1) as total_1,
(cost_2 * quantity_2) as total_2
from data
) t
Il n'y aura aucune pénalité de performance à ce sujet.
(Je suis vraiment surpris que votre instruction SQL d'origine s'exécute dans un SGBD)
Si vous n'aimez pas encapsuler la requête entière avec une requête externe, vous pouvez utiliser LATERAL
pour calculer l'intermédiaire total_1
et total_2
:
SELECT cost_1, quantity_1, cost_2, quantity_2, total_1, total_2,
total_1 + total_2 AS total_3
FROM data
,LATERAL(SELECT cost_1 * quantity_1, cost_2 * quantity_2) AS s1(total_1,total_2);
Production:
╔═════════╦═════════════╦═════════╦═════════════╦══════════╦══════════╦═════════╗
║ cost_1 ║ quantity_1 ║ cost_2 ║ quantity_2 ║ total_1 ║ total_2 ║ total_3 ║
╠═════════╬═════════════╬═════════╬═════════════╬══════════╬══════════╬═════════╣
║ 1 ║ 2 ║ 3 ║ 4 ║ 2 ║ 12 ║ 14 ║
║ 3 ║ 5 ║ 7 ║ 9 ║ 15 ║ 63 ║ 78 ║
║ 10 ║ 5 ║ 20 ║ 2 ║ 50 ║ 40 ║ 90 ║
╚═════════╩═════════════╩═════════╩═════════════╩══════════╩══════════╩═════════╝
En règle générale, il y a deux choses que vous devez savoir sur la clause SELECT
:
ORDER BY
clause. C'est pourquoi vous ne pouvez pas utiliser de champs calculés ou d'alias dans une autre clause (en particulier la clause WHERE
) sauf dans le ORDER BY
clause.SELECT
sont effectués en parallèle , ou au moins sont traités comme s'ils l'étaient. C'est pourquoi vous ne pouvez pas utiliser un calcul dans le cadre d'un autre.Donc, la réponse courte est que vous ne pouvez pas, et c'est par conception.
L'exception notable à cela est Microsoft Access, où vous pouvez en effet utiliser des calculs dans les colonnes suivantes et les clauses WHERE
. Cependant, bien que cela soit pratique, ce n'est pas vraiment un avantage: ne pas suivre les principes ci-dessus est moins efficace. Mais c'est OK pour les bases de données légères, pour lesquelles Access est censé être utilisé.
Si vous voulez vraiment réutiliser les résultats calculés, vous aurez besoin d'une requête distincte, soit sous la forme d'une sous-requête, soit en tant qu'expression de table commune. Les CTE sont beaucoup plus faciles à utiliser, car ils sont plus lisibles.
Modifier
Sans changer le point de la réponse originale, j'ai pensé que je pourrais ajouter que je pense que cette explication est peut-être un peu mesquin.
Les SGBD modernes mettent beaucoup d'efforts dans la planification et l'optimisation des requêtes, il n'est donc plus correct, si jamais, que la requête est réellement exécutée dans un ordre particulier. Pour autant que je sache, il n'y a aucune raison technique pour laquelle l'optimiseur ne pouvait pas anticiper et incorporer les résultats calculés dans l'analyse de la requête, même s'il est seulement de substituer des expressions.
Tant pis …
select cost_1, quantity_1, cost_2, quantity_2,
cost_1 * quantity_1 as total_1,
cost_2 * quantity_2 as total_2,
(cost_1 * quantity_1 + cost_2 * quantity_2) as total_3
from data;