it-swarm.com.de

So verwenden Sie eine Ergebnisspalte in einem Ausdruck für eine andere Ergebnisspalte

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?

43
Wernight

So wie:

SELECT
   turnover,
   cost,
   turnover - cost as profit
from (
   (SELECT SUM(...) FROM ...) as turnover,
   (SELECT SUM(...) FROM ...) as cost
   ) as partial_sums
42

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.

12

Vielleicht könnte die SQL-Klausel "with" helfen, wie hier http://orafaq.com/node/1879 (andere Datenbanken wie Postgres, nicht nur Oracle).

6
andrers52

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.

4
bhealy
SELECT turnover, cost, turnover - cost
FROM
(
SELECT
(SELECT ...) as turnover,
(SELECT ...) as cost
) as Temp
4
Eric.K.Yung

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.

3
Bob Jarvis

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
0
William Egge

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.

0
Niklas