Mehrere Columns selecten bei Joins

Kampfgummibaerlie

Datenbank-Guru
Beiträge
743
Habe recht lange gebraucht, bis ich das überrissen habe...

Man kann nur direkt nach einem select mit dieser Tabelle joins erstellen :/

Mein Beispiel für eine Ansicht war dann das:
Code:
create view view_maschinentypenauslastung_in_woche as SELECT avg(date_part('week'::text, lower(vermietungen.mietzeit))) AS woche,
 maschinentypen.name, avg(tsrange_diff(vermietungen.mietzeit)) / sum(timerange_diff("öffnungszeiten"."öffnungszeit")) * 100::numeric AS
 anteil_prozent FROM vermietungen JOIN maschinen ON vermietungen.maschine = maschinen.id JOIN maschinentypen ON maschinentypen.id =
 maschinen.typ, "öffnungszeiten" GROUP BY (date_part('week'::text, lower(vermietungen.mietzeit))), maschinentypen.name;

diese Ansicht zeigt mir die Nutzung eines maschinentyps in der kalenderwoche in Prozent an... =D
wieder was gelernt xD

EDIT: Die Logik dahinter ganz vergessen, man Joined eine andere tabelle, indem man direkt nach dem "from table" den join anhängt...

LG Kampfgummibaerlie
 
Werbung:
Ja, so ist das.
Man kann das auch sichtbar(er) machen, Formatierung hat schon ihren Wert:

Code:
create view view_maschinentypenauslastung_in_woche as 
SELECT avg(date_part('week' ::text, lower(vermietungen.mietzeit))) AS woche,
       maschinentypen.name,
       avg(tsrange_diff(vermietungen.mietzeit)) /
       sum(timerange_diff("öffnungszeiten"."öffnungszeit")) * 100 ::numeric AS anteil_prozent
  FROM vermietungen
  JOIN maschinen
    ON vermietungen.maschine = maschinen.id
  JOIN maschinentypen
    ON maschinentypen.id = maschinen.typ, "öffnungszeiten"
 GROUP BY (date_part('week' ::text, lower(vermietungen.mietzeit))),
          maschinentypen.name;

und das hat nichts mit Views zu tun, Views sind nur Namen für Select Statements. Joins sind ein Bestandteil von Select Statements:

Code:
SELECT avg(date_part('week' ::text, lower(vermietungen.mietzeit))) AS woche,
       maschinentypen.name,
       avg(tsrange_diff(vermietungen.mietzeit)) /
       sum(timerange_diff("öffnungszeiten"."öffnungszeit")) * 100 ::numeric AS anteil_prozent
  FROM vermietungen
  JOIN maschinen
    ON vermietungen.maschine = maschinen.id
  JOIN maschinentypen
    ON maschinentypen.id = maschinen.typ, "öffnungszeiten"
 GROUP BY (date_part('week' ::text, lower(vermietungen.mietzeit))),
          maschinentypen.name;

Bedeutet auch, das jedes Select Statement ein View sein kann, gehört aber gar nicht zum Thema Join.
Joins sind ein elementarer Bestandteil von SQL, Mengen basierte Datenverarbeitung.
usw. usw. steht alles in den Dokus, nicht nur die Syntax. Ein Join gehört hinter die From Clause. SQL ohne Joins zu verwenden ist ungefähr Excel.

:)
 
er meinte bei mir heute, keine Ahnung mehr wie der Syntax exakt aussah, gemeint "Tabelle Vermietungen kommt vor, steht aber an der falschen Stelle"...

es geht mir explizit um folgendes:
Code:
 SELECT avg(date_part('week'::text, lower(vermietungen.mietzeit))) AS woche,
    maschinentypen.name,
    avg(tsrange_diff(vermietungen.mietzeit)) / sum(timerange_diff("öffnungszeiten"."öffnungszeit")) * 100::numeric AS anteil_prozent
   FROM vermietungen
     JOIN maschinen ON vermietungen.maschine = maschinen.id
     JOIN maschinentypen ON maschinentypen.id = maschinen.typ,
    "öffnungszeiten"
  GROUP BY (date_part('week'::text, lower(vermietungen.mietzeit))), maschinentypen.name;

funktioniert...

Code:
 SELECT avg(date_part('week'::text, lower(vermietungen.mietzeit))) AS woche,
    maschinentypen.name,
    avg(tsrange_diff(vermietungen.mietzeit)) / sum(timerange_diff("öffnungszeiten"."öffnungszeit")) * 100::numeric AS anteil_prozent
   FROM vermietungen, öffnungszeiten
     JOIN maschinen ON vermietungen.maschine = maschinen.id
     JOIN maschinentypen ON maschinentypen.id = maschinen.typ
  GROUP BY (date_part('week'::text, lower(vermietungen.mietzeit))), maschinentypen.name;

funktioniert nicht ;)

Error hier:
Code:
ERROR:  ungültiger Verweis auf FROM-Klausel-Eintrag für Tabelle »vermietungen«LINE 5:      
JOIN maschinen ON vermietungen.maschine = maschinen.id                               
^HINT:  Es gibt einen Eintrag für Tabelle »vermietungen«, aber auf ihn kann aus diesem Teil der Anfrage nicht verwiesen werden. 
FEHLER:  ungültiger Verweis auf FROM-Klausel-Eintrag für Tabelle »vermietungen«SQL-Status: 42P01Zeichen: 296

Wollte nur betont sagen, dass man, wenn man joinen möchte, direkt nach dem FROM auch die Joins zu der Tabelle schreiben muss, damit der Fehler eben nicht kommt.

EDIT: Den Fehler vollständig hier reinkopiert.
 
Du vermischt die veralteten impliziten joins die mit Komma getrennt im FROM stehen und die "modernen" (seit 1989) Joins mit einem expliziten JOIN Operator. Mach es Dir zur Grundlegen im FROM Teil niemals ein Komma zu verwenden. Wenn Du einen cross join willst, dann schreib das auch:

Code:
FROM vermietungen
  CROSS JOIN "öffnungszeiten"
  JOIN maschinen ON vermietungen.maschine = maschinen.id
  JOIN maschinentypen ON maschinentypen.id = maschinen.typ
GROUP BY (date_part('week'::text, lower(vermietungen.mietzeit))), maschinentypen.name;
 
Werbung:
Jetzt versteh ich Dein "Problem".

Falls Du irgendwo solchen alten Code findest *, ob Cross Join oder andere Varianten, hier ist ein Beispiel:
Code:
postgres=# create table this (id serial, this_name varchar(10));insert into this (this_name) values ('A'), ('b'), ('c');
CREATE TABLE
INSERT 0 3
postgres=# create table that (id serial, this_id bigint, that_name varchar(10));insert into that (this_id, that_name) values (1, 'b'), (2, 'a');
CREATE TABLE
INSERT 0 2
postgres=# create view this_and_that as
postgres=# select string_agg(i.this_name||a.that_name,'') all_together
postgres=#   from this i, that a               -- < "old school" from clause
postgres=#  where i.id = a.this_id;            -- < join Kriterium in der where clause
CREATE VIEW
postgres=# select all_together from this_and_that;
all_together
_____________
Abba
Wenn Du die Where Clause entfernst, hast Du den Cross Join und das Ergebnis lässt sich schlechter lesen als das Beispiel mit implizitem Join in der Where Clause.
Ich finde es zu Lernzwecken eigentlich ganz gut, diese alte Form zu kennen, weil sie eigentlich besser zeigt, was geschieht.
Technisch gesehen passiert sicher das gleiche wie bei einem modernen Join.
Aber es ist schlechter les- und unterscheidbar. Und sicher noch wichtiger, es ist zu befürchten, dass der Optimizer damit nicht so gut umgehen kann. Die Abfragen sind also langsamer.
Last but not least, man hat damit weniger Ausdrucksmöglichkeiten für Outer Joins u.ä.
Wenn man es also verstanden hat, kann man es einfach vergessen, außer im Fall "alter Code"*

* Wenn man sowas im Netz oder in der FirmenDB findet, sollte man wissen, was das ist.
 
Zurück
Oben