103 votes

Comment utiliser une colonne calculée pour calculer une autre colonne dans la même vue

Je compte sur votre aide pour cette question. J'utilise Oracle SQL (SQL Developer pour cette vue)...

Si j'ai une table avec les colonnes suivantes :

  • ColumnA (Number)
  • ColumnB (Number)
  • ColumnC (Number)

Dans ma vue j'ai

Select  
ColumnA,
ColumnB,
ColumnA + ColumnB As calccolumn1

Maintenant, à ce stade, je veux utiliser calccolumn1 mais je ne peux pas juste dire...

Select  
ColumnA,
ColumnB,
ColumnA + ColumnB As calccolumn1
calccolumn1 / ColumnC as calccolumn2

Je suppose que j'ai besoin d'un type de sous-requête... c'est là que j'ai besoin de votre aide... Comment formulerais-je la requête pour pouvoir utiliser calccolumn1 dans un autre calcul dans la même requête ? Il pourrait s'agir d'un If alors ou d'un Case when, mais au final c'est un nombre dérivé.

76voto

Alex Poole Points 43006

Vous pourriez utiliser une requête imbriquée :

Sélectionner
  ColumnA,
  ColumnB,
  calccolumn1,
  calccolumn1 / ColumnC as calccolumn2
De (
  Sélectionner
    ColumnA,
    ColumnB,
    ColumnC,
    ColumnA + ColumnB Comme calccolumn1
  de t42
);

Avec une ligne de valeurs 3, 4, 5 cela donne :

   COLUMNA    COLUMNB CALCCOLUMN1 CALCCOLUMN2
---------- ---------- ----------- -----------
         3          4           7         1.4

Vous pouvez également simplement répéter le premier calcul, sauf s'il effectue vraiment une opération coûteuse (via un appel de fonction, par exemple) :

Sélectionner
  ColumnA,
  ColumnB,
  ColumnA + ColumnB Comme calccolumn1,
  (ColumnA + ColumnB) / ColumnC Comme calccolumn2
de t42; 

   COLUMNA    COLUMNB CALCCOLUMN1 CALCCOLUMN2
---------- ---------- ----------- -----------
         3          4           7         1.4

36voto

Manoj Points 3537

Dans Sql Server

Vous pouvez le faire en utilisant cross apply

Sélectionner
  ColonneA,
  ColonneB,
  c.calccolonnet1 Comme calccolonnet1,
  c.calccolonnet1 / ColonneC Comme calccolonnet2
de t42
cross apply (sélectionner (ColonneA + ColonneB) comme calccolonnet1) comme c

18voto

lad2025 Points 38168

Si vous voulez faire référence à une colonne calculée sur le "même niveau de requête", alors vous pouvez utiliser CROSS APPLY (Oracle 12c) :

--Données d'exemple :
CREATE TABLE tab(ColumnA NUMBER(10,2),ColumnB NUMBER(10,2),ColumnC NUMBER(10,2));

INSERT INTO tab(ColumnA, ColumnB, ColumnC) VALUES (2, 10, 2);
INSERT INTO tab(ColumnA, ColumnB, ColumnC) VALUES (3, 15, 6);
INSERT INTO tab(ColumnA, ColumnB, ColumnC) VALUES (7, 14, 3);
COMMIT;

Requête :

SELECT
  ColumnA,
  ColumnB,
  sub.calccolumn1,
  sub.calccolumn1 / ColumnC AS calccolumn2
FROM tab t
CROSS APPLY (SELECT t.ColumnA + t.ColumnB AS calccolumn1 FROM dual) sub;

Démo DBFiddle


Veuillez noter que l'expression de CROSS APPLY/OUTER APPLY est également disponible dans d'autres clauses :

SELECT
  ColumnA,
  ColumnB,
  sub.calccolumn1,
  sub.calccolumn1 / ColumnC AS calccolumn2
FROM tab t
CROSS APPLY (SELECT t.ColumnA + t.ColumnB AS calccolumn1 FROM dual) sub
WHERE sub.calccolumn1 = 12;
-- GROUP BY ...
-- ORDER BY ...;

Cette approche permet d'éviter d'envelopper toute la requête avec une sous-requête ou de copier/coller la même expression à plusieurs endroits (avec une complexe, cela pourrait être difficile à maintenir).

Article connexe : La fonctionnalité la plus manquante du langage SQL

8voto

swirlingsara Points 105

Vous devez inclure l'expression pour votre colonne calculée:

SELECT  
ColumnA,  
ColumnB,  
ColumnA + ColumnB AS calccolumn1  
(ColumnA + ColumnB) / ColumnC AS calccolumn2

3voto

**Dans SQL Server

Vous pouvez le faire en utilisant With CTE**

AVEC common_table_expression (Transact-SQL)

CREATE TABLE tab(ColumnA DECIMAL(10,2), ColumnB DECIMAL(10,2), ColumnC DECIMAL(10,2))

INSERT INTO tab(ColumnA, ColumnB, ColumnC) VALUES (2, 10, 2),(3, 15, 6),(7, 14, 3)

WITH tab_CTE (ColumnA, ColumnB, ColumnC,calccolumn1)  
AS  
(  
Select
    ColumnA,
    ColumnB,
    ColumnC,
    ColumnA + ColumnB As calccolumn1
  from tab
)  

SELECT
  ColumnA,
  ColumnB,
  calccolumn1,
  calccolumn1 / ColumnC AS calccolumn2
FROM  tab_CTE

Démo DBFiddle

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X