Exemple:
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost,
turnover - cost as profit
Bien sûr, cela n’est pas valide (du moins dans Postgres), mais comment obtenir la même chose dans une requête sans réécrire la sous-requête deux fois?
Ainsi:
SELECT
turnover,
cost,
turnover - cost as profit
from (
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost
) as partial_sums
Vous pouvez réutiliser la requête comme ceci:
WITH
TURNOVER AS (
SELECT SUM(...) FROM ...)
),
COST AS(
SELECT SUM(...) FROM ...
)
SELECT *
FROM(
SELECT
TURNOVER.sum as SUM_TURNOVER
FROM
TURNOVER,COST
WHERE ....
) AS a
Ceci est équivalent à:
SELECT *
FROM(
SELECT
TURNOVER.sum as SUM_TURNOVER
FROM
(
SELECT SUM(...) FROM ...)
)AS TURNOVER,
(
SELECT SUM(...) FROM ...
)AS COST
WHERE ....
) AS a
Il y a un point à noter ici. La première méthode est plus lisible et réutilisable, mais la deuxième peut être plus rapide, car la base de données peut choisir un meilleur plan pour elle.
La clause "with" de SQL pourrait peut-être aider, comme présenté ici http://orafaq.com/node/1879 (d’autres bases de données telles que Postgres le font aussi, pas seulement Oracle).
En fait, j’ai beaucoup travaillé sur ce sujet et j’ai heurté de nombreux murs de briques, mais j’ai finalement trouvé une réponse - plutôt un bidouillage - mais cela fonctionnait très bien et réduisait le temps de lecture de mes requêtes de 90% ...
Ainsi, plutôt que de dupliquer plusieurs fois la requête corrélée pour récupérer plusieurs colonnes de la sous-requête, je viens d’utiliser Concat toutes les valeurs que je souhaite renvoyer dans un varchar séparé par des virgules, puis de les dérouler à nouveau dans l’application ...
Donc au lieu de
select a,b,
(select x from bigcorrelatedsubquery) as x,
(select y from bigcorrelatedsubquery) as y,
(select z from bigcorrelatedsubquery) as z
from outertable
Je fais maintenant
select a,b,
(select convert(varchar,x)+','+convert(varchar,x)+','+convert(varchar,x)+','
from bigcorrelatedsubquery) from bigcorrelatedquery) as xyz
from outertable
group by country
J'ai maintenant les trois valeurs «scalaires» corrélées dont j'avais besoin mais je n'avais qu'à exécuter la sous-requête corrélée une fois au lieu de trois fois.
SELECT turnover, cost, turnover - cost
FROM
(
SELECT
(SELECT ...) as turnover,
(SELECT ...) as cost
) as Temp
Je pense que ce qui suit fonctionnera:
SELECT turnover, cost, turnover-cost as profit FROM
(SELECT 1 AS FAKE_KEY, SUM(a_field) AS TURNOVER FROM some_table) a
INNER JOIN
(SELECT 1 AS FAKE_KEY, SUM(a_nother_field) AS COST FROM some_other_table) b
USING (FAKE_KEY);
Non testé sur les animaux - vous serez le premier! :-)
Partager et profiter.
Utilisez une application en croix ou externe.
SELECT
Calc1.turnover,
Calc2.cost,
Calc3.profit
from
cross apply ((SELECT SUM(...) as turnover FROM ...)) as Calc1
cross apply ((SELECT SUM(...) as cost FROM ...)) as Calc2
/*
Note there is no from Clause in Calc 3 below.
This is how you can "stack" formulas like in Excel.
You can return any number of columns, not just one.
*/
cross apply (select Calc1.turnover - Calc2.cost as profit) as Calc3
c'est assez vieux mais j'ai rencontré ce problème et vu ce post mais je n'ai pas réussi à résoudre mon problème en utilisant les réponses données donc je suis finalement arrivé à cette solution:
si votre requête est:
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost,
turnover - cost as profit
vous pouvez le transformer en une sous-requête puis utiliser les champs tels que:
SELECT *,(myFields.turnover-myFields.cost) as profit
FROM
(
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost
) as myFields
je ne suis pas tout à fait sûr que ce soit une mauvaise façon de faire les choses, mais en termes de performances, cela me semble correct d'interroger des enregistrements 224,000
prend 1,5 seconde.