View mit abhängigen Views bearbeiten

Werbung:
Ich möchte das ganze ja gerne als VIEW haben. Wenn ich jetzt die Where Klausel mit dem Jahr in der VIEW Definition weglasse, wird ja schon die Aggregationsfunktion Summe auf alle - ungefilterte Tupel der Tabelle p angewendet, ohne Berücksichtigung des Jahres. Mit einer Where - Klausel auf die VIEW kann ich ja nichts mehr an den summierten Tupeln ändern, oder wo ist mein Denkfehler?
 
vielleicht mal ein nachvollziehbares Beispiel...

Code:
edb=> create table t1 as select * from generate_series(1,10) s;
SELECT 10
edb=*> create view view_t1 as select * from t1 where s between 3 and 7;
CREATE VIEW
edb=*> select * from view_t1 where s between 4 and 6;
 s
---
 4
 5
 6
(3 rows)

edb=*> select * from view_t1 where s between 5 and 10;
 s
---
 5
 6
 7
(3 rows)

edb=*>
 
Da hast du ja aber auch keine Aggregatfunktion drin, wie z.B. SUM().
Probiere gerne mal anhand dieser Beispieltabellen

Code:
create table s ( bezeichnung text, sID integer) ;
insert into s values('s1',1),('s2',2),('s3',3);
create table p ( pID integer, sID integer, a int, b int, jahr1 int, jahr2 int);
insert into p values (1,1,2,1,2000,2021),(2,1,3,2,2000,null),(3,1,10,3,2000,2008),(4,2,1,2,2019,null),(5,2,1,3,2019,null),(6,3,5,2,2000,2005);

Die Funktionalität dieses Codes als View zu implementieren, mit der Möglichkeit das Jahr als SELECT Abfrage auf die VIEW abzufragen.

Code:
SELECT
    s.sid,
    s.bezeichnung,
    sum(p.a * p.b) AS flaeche
   FROM s,p
  WHERE s.sid = p.sid
  AND p.jahr1 <= 2004 AND ((p.jahr2) >= 2004 OR p.jahr2 IS NULL)
  GROUP BY s.sid,s.bezeichnung;
Ich würde sonst halt einfach eine Funktion schreiben, und dann eine View mit dem aktuellen Jahr (diese Abfrage wird am häufigsten gebraucht) erstellen, aber bin auf deinen Vorschlag gespannt.

Gruß Ludwig
 
Also in dem speziellen Fall dann eine Function?

halte ich für solch eher einfachen Abfragen eher für übertrieben, aber das ist sicherlich auch Ansichtssache. Könnte ja auch sein, daß für 'normale' Benutzer Zugriffe auf die Tabellen direkt nicht erfolgen sollen, und über solche Funktionen und weiteren Sicherheitsmaßnahmen eine Art API zur Verfügung gestellt wird.
 
Ja, das ist so eine Situation wo eine Funktion tatsächlich einfacher ist als eine View.

Eine kleine Bemerkung zu dieser Bedingung:

Code:
AND p.jahr1 <= 2004 AND ((p.jahr2) >= 2004 OR p.jahr2 IS NULL)

"oder" Bedingungen sind für die Optimizer relationaler Datenbanken üblicherweise sehr schwer zu optimieren und Postgres macht da leider keine Ausnahme.

Normalerweise bin ich kein Fan von "magic numbers" aber bei Bereichsabfragen (>, < usw) kann man da eine Ausnahme machen, wenn man dafür ein OR IS NULL vermeiden kann. Wenn das ein DATE wäre hätte ich vorgeschlagen, statt NULL einfach 'infinity' zu speichern (um ein Datum irgendwann in der Zukunft zu speichern). Wenn Du aber nur das Jahr als Zahl speicherst, würde es vielleicht Sinn machen stattdessen z.B.: 9999 zu verwenden um damit das OR IS NULL loszuwerden (leider gibt es bei int und numeric kein 'infinity', nur bei "real" und "double precision")

Das kannst Du ja im Hinterkopf behalten wenn es da mal Performance Probleme geben sollte.
 
Ich sagte ja, dass ich das normalerweise nicht mag. Aber die OR IS NULL Bedingungen sind sehr häufig ein Performance-Killer.

Wenn überhaupt mache ich das auch nur für Spalten, die mit > bzw < verglichen werden.

Am schönsten wäre natürlich ein DATE mit 'infinity' ;)
 
Werbung:
Zurück
Oben