Beispiel:
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost,
turnover - cost as profit
Sicher, das ist ungültig (zumindest in Postgres), aber wie erreicht man dasselbe in einer Abfrage, ohne die Unterabfrage zweimal neu zu schreiben?
So wie:
SELECT
turnover,
cost,
turnover - cost as profit
from (
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost
) as partial_sums
Sie können die Abfrage wie folgt wiederverwenden:
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
Das ist äquivalent zu:
SELECT *
FROM(
SELECT
TURNOVER.sum as SUM_TURNOVER
FROM
(
SELECT SUM(...) FROM ...)
)AS TURNOVER,
(
SELECT SUM(...) FROM ...
)AS COST
WHERE ....
) AS a
Hier ist ein Punkt zu beachten. Die erste Methode ist besser lesbar und wiederverwendbar, die zweite Methode ist jedoch möglicherweise schneller, da der DB möglicherweise einen besseren Plan dafür wählt.
Vielleicht könnte die SQL-Klausel "with" helfen, wie hier http://orafaq.com/node/1879 (andere Datenbanken wie Postgres, nicht nur Oracle).
Eigentlich habe ich viel daran gearbeitet und viele Backsteinmauern getroffen, aber schließlich fand ich eine Antwort - eher ein Hack -, die aber sehr gut funktionierte und den Leseaufwand meiner Abfragen um 90% reduzierte.
Anstatt die korrelierte Abfrage viele Male zu duplizieren, um mehrere Spalten aus der Unterabfrage abzurufen, habe ich einfach alle Werte verwendet, die ich in einen durch Kommas getrennten varchar zurückgeben möchte, und sie dann in der Anwendung wieder aufrollen ...
Also statt
select a,b,
(select x from bigcorrelatedsubquery) as x,
(select y from bigcorrelatedsubquery) as y,
(select z from bigcorrelatedsubquery) as z
from outertable
Mache ich jetzt
select a,b,
(select convert(varchar,x)+','+convert(varchar,x)+','+convert(varchar,x)+','
from bigcorrelatedsubquery) from bigcorrelatedquery) as xyz
from outertable
group by country
Ich habe jetzt alle drei korrelierten 'skalaren' Werte, die ich brauchte, aber ich musste die korrelierte Unterabfrage nur einmal statt dreimal ausführen.
SELECT turnover, cost, turnover - cost
FROM
(
SELECT
(SELECT ...) as turnover,
(SELECT ...) as cost
) as Temp
Ich denke, das Folgende wird funktionieren:
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);
Nicht an Tieren getestet - Sie sind der Erste! :-)
Teile und genieße.
Verwenden Sie ein Kreuz oder einen äußeren Auftrag.
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
dies ist ziemlich alt, aber ich bin auf dieses Problem gestoßen und habe diesen Beitrag gesehen, aber es ist mir nicht gelungen, mein Problem mit den gegebenen Antworten zu lösen, also bin ich schließlich zu dieser Lösung gekommen:
wenn Ihre Anfrage lautet:
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost,
turnover - cost as profit
sie können es in eine Unterabfrage umwandeln und dann die folgenden Felder verwenden:
SELECT *,(myFields.turnover-myFields.cost) as profit
FROM
(
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost
) as myFields
ich bin mir nicht ganz sicher, ob dies ein schlechter Weg ist, aber aus Performancegründen ist es okay für mich, 224,000
-Datensätze abzufragen. Es dauerte 1,5 Sekunden.