Exemple:
SELECT (SELECT SUM(...) FROM ...) as turnover, (SELECT SUM(...) FROM ...) as cost, turnover - cost as profit
Bien sûr, cela est invalide (au 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 seconde méthode peut être plus rapide, car la firebase database peut choisir un meilleur plan.
Peut-être que la clause sql “with” pourrait aider, comme présenté ici http://orafaq.com/node/1879 (d’autres bases de données telles que Postgres le font également, pas seulement Oracle).
SELECT turnover, cost, turnover - cost FROM ( SELECT (SELECT ...) as turnover, (SELECT ...) as cost ) as Temp
En fait, j’ai fait beaucoup de travail là-dessus et j’ai heurté de nombreux murs de briques, mais j’ai finalement trouvé une réponse – plus un hack – mais cela a très bien fonctionné et a réduit de 90% le temps de lecture de mes requêtes ….
Donc, plutôt que de dupliquer la requête corrélée plusieurs fois pour récupérer plusieurs colonnes de la sous-requête, je viens d’utiliser concaténer toutes les valeurs que je veux 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 devais seulement exécuter la sous-requête corrélée une fois au lieu de trois.
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);
Pas testé sur les animaux – vous serez le premier! 🙂
Partager et profiter.
Vous pouvez utiliser des variables définies par l’utilisateur comme ceci
SELECT @turnover := (SELECT SUM(...) FROM ...), @cost := (SELECT SUM(...) FROM ...), @turnover - @cost as profit
Utilisez une croix appliquer ou appliquer à l’extérieur.
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 j’ai 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, mais en ce qui concerne les 224,000
enregistrements, il me semble que 1,5 s ne serait pas sûr de le transformer en 2x de la même requête par DB.