Alias in Kalkulation

magpie

Benutzer
Beiträge
14
Ich möchte in einem Select mit Alias rechnen, es kommt aber immer die Fehlermeldung, dass die Spalte nicht existiert.
SQL:
select
    1 as a,
    2 as b,
    (a+b) as c;
Dies ist nur ein Beispiel. Im eigentlichen Code kommt der Inhalt der Aliase von Subquerys. Ich möchte ungern die Subquerys in der Kalkulation noch einmal aufrufen.
SQL:
select
    (select ...) as a,
    (select ...) as b,
    (a + b) as c
from ...

Gibt es da eine Möglichkeit?
 
Werbung:
Meine Angehensweise wäre, falls die Werte in Tabellen liegen:

Code:
select a, b, a+b as c from ...
Hinweis: Rechenoperationen sind bei selects erlaubt ;)
du verwendest Sub-Selects, wo sie offenbar nicht notwendig sind!

Ein praktisches Beispiel:
Code:
create table tabelle(a integer, b integer);

Code:
insert into tabelle values (1, 1);

Code:
select a, b, a+b as c from tabelle;

Ergebnis:
Code:
1 - 1 - 2
 
Eine andere, aber aufwendigere Angehensweise wäre mit rekursiven Abfragen

Beispielcode:
Code:
with recursive a(b, c, d) as (select 1 as b, 1 as c, 1 as d union select b+1, c+1, b+c from a where b < 50) select * from a;

Dafür brauchst du keine Tabelle mehr, die die Werte enthält, nur, wenn das so sein muss frage ich mich, wofür die Datenbank dient ;)

EDIT:
Mir fallt auf, dass du in der 3. Spalte ein "Sub-Select" einsetzt (durch die Klammer), wo er dann einen weiteren Select-Befehl erwartet, das müsste dann so aussehen:
Code:
select
    (select ...) as a,
    (select ...) as b,
    (select a + b) as c
from ...
 
du kannst nicht auf Aliase im selben Level zugreifen. Dazu hat IIRC mal Tom Lane vor zig Jahren ein lägliches Statement gegeben, in kurz: ist so wegen SQL-Spec. Würde man das implementieren, würde andere Dinge einem um den Kopf fliegen.

Lösung: wenn es im selben Level nicht geht, dann ein extra Level einbauen:

Code:
postgres=# select 1 as a, 2 as b, a+b;
ERROR:  column "a" does not exist
LINE 1: select 1 as a, 2 as b, a+b;
                               ^
postgres=# with foo as (select 1 as a, 2 as b) select a+b from foo;
 ?column? 
----------
        3
(1 row)

postgres=#
 
Danke für eure Antworten. Ich werde den Ansatz von @akretschmer mal versuchen.

Ich möchte die Ausgaben mit dem Budget vergleichen. Die Ausgaben kommen aber aus anderen Tabellen. Das Ausgeben-der Budget- und Ausgabenwerte klappt. Ich möchte aber noch die Differenz ausgeben. Dafür muss ich die beiden Werte miteinander verrechnen.
SQL:
select
    b.id,
    b.name,
    b.start_date,
    b.end_date,
    br.id,
    br.account,
    br.debit_amount,
    br.credit_amount,
    (
        select
            sum(lr.amount) as debit
        from
            ledger_record lr
            left join ledger l on lr.ledger = l.id
        where
            lr.debit_account = a.id
            and l.booking_date between b.start_date and b.end_date
        group by
            lr.debit_account
    ) as debit_sum,
    (
        select
            sum(lr.amount) as credit
        from
            ledger_record lr
            left join ledger l on lr.ledger = l.id
        where
            lr.credit_account = a.id
            and l.booking_date between b.start_date and b.end_date
        group by
            lr.credit_account
    ) as credit_sum,
    br.debit_amount - debit_sum as debit_balance -- da liegt das Problem
    br.credit_amount - credit_sum as credit_balance -- da liegt das Problem
from
    budget b
    left join budget_record br on b.id = br.budget_id
    left join account a on br.account = a.id
where
   a.id in (select id from matview_account_tree where level = 4);
 
noch ein Nachtrag: in älteren Versionen wurden die via with ... geschaffenen Tabellen echt materialisiert, selbst wenn weiter höher eine WHERE-Condition greifen könnte. In aktuellen Versionen, so ab 10 oder so, ist das besser, da wird ein WHERE auch passend nach unten durchgereicht.
 
Werbung:
Mit WITH hat es nach einigem basteln geklappt. Das mit dem WHERE habe ich nicht ganz verstanden, spielt bei mir aber keine Rolle. Ich hatte vor allem das Problem, dass ich in allen SELECT's das gleichen Konto als Bedingung benötige. Mit den klassischen Subquerys gibt das wunderbar. Mit WITH war das kniffliger :)
 
Zurück
Oben