PostgreSQL: utiliser une colonne calculée dans la même requête

j'ai de la difficulté à utiliser une colonne calculée dans postgres. Un code similaire qui fonctionne en SQL est donné ci-dessous, est-il possible de le recréer en 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;

PostgreSQL un code similaire renvoie l'erreur:

les colonnes total_1 et total_2 n'existent pas.

29
demandé sur Lukasz Szozda 2012-01-12 22:23:03

5 réponses

vous devez envelopper la déclaration SELECT dans une table dérivée afin de pouvoir accéder à la colonne alias:

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 pas de perte de performances.

(je suis vraiment surpris de voir que l'original de votre instruction SQL s'exécute dans un SGBD)

32
répondu a_horse_with_no_name 2012-01-12 20:35:40

si vous n'aimez pas wraping requête entière avec outerquery, vous pouvez utiliser LATERAL pour calculer 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);

Dbfiddle Demo

Sortie:

╔═════════╦═════════════╦═════════╦═════════════╦══════════╦══════════╦═════════╗
║ 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 ║
╚═════════╩═════════════╩═════════╩═════════════╩══════════╩══════════╩═════════╝
17
répondu Lukasz Szozda 2018-05-06 07:10:40

en règle générale, il y a deux choses que vous devez savoir sur le SELECT l'article:

  • bien qu'il soit écrit premier, il est évalué dernière, à l'exception de l' ORDER BY l'article. C'est pourquoi vous ne pouvez pas utiliser de champs calculés ou d'alias dans une autre clause (en particulier WHERE l'article) sauf dans le ORDER BY l'article.
  • Calculs dans le SELECT la clause est exécutée en parallèle, ou du moins sont manipulés comme s'ils l'étaient. C'est pourquoi vous ne pouvez pas utiliser un calcul comme faisant partie d'un autre.

Donc, la réponse courte est que vous ne pouvez pas, et c'est par la conception.

L'exception notable à cela est Microsoft Access, où vous pouvez en effet utiliser des calculs dans les colonnes suivantes et WHERE les clauses. 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 de service léger, ce qui est ce à quoi L'accès est censé être utilisé.

si vous voulez vraiment réutiliser les résultats calculés, vous aurez besoin d'une requête séparée, soit sous la forme d'une sous-requête ou comme une Expression commune de Table. Les CTE sont beaucoup plus faciles à utiliser, car ils sont plus clairs à lire.

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.

Moderne Sgbd mis beaucoup d'efforts dans la planification et l'optimisation de requêtes, de sorte qu'il n'est plus correct, si jamais, que la requête est réellement exécutées dans un ordre particulier. Pour autant que je puisse voir, il n'y a pas de technique raison pour laquelle l'optimiseur ne pouvait pas regarder à l'avance et incorporer des résultats calculés dans l'analyse de la requête, même si c'est seulement pour substituer des expressions.

eh bien ...

7
répondu Manngo 2018-03-07 10:19:58
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;
0
répondu Sarah 2018-07-20 23:51:57

Vous essayez d'utiliser un alias de colonne dans une expression. Si un système vous permet de faire ça, c'est juste du sucre syntaxique. Cela devrait fonctionner dans n'importe quel dialecte SQL.

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;
-2
répondu tponthieux 2012-01-12 18:33:40