JOIN mit meheren Tabellen in Abhängigkeit

Hey All,

ich habe Kunden, Lieferanten und Personen (Ansprechpartner).

Die Personen können zu Kunde oder zu Lieferanten gehören.
Nun möchte ich mit einem JOIN Person und Kunden holen oder Person und Lieferant - je nach dem ob die Person zum Kunden oder zum Lieferanten gehört.

DROP  TABLE IF EXISTS personen;
CREATE TABLE personen( id SERIAL, name TEXT );
INSERT INTO personen ( name ) VALUES ( 'Ronny Zimmermann' );
INSERT INTO personen ( name ) VALUES ( 'Dirk Schwatzer' );
SELECT * FROM personen;


DROP  TABLE IF EXISTS kunden;
CREATE TABLE kunden( id SERIAL, name TEXT, person_id INT );
INSERT INTO kunden ( name ) VALUES ( 'Glaserei Falkenberg' );
INSERT INTO kunden ( name, person_id ) VALUES ( 'Bautech', 2 );
--SELECT * FROM kunden;

DROP  TABLE IF EXISTS liefe;
CREATE TABLE liefe( id serial, name text,  person_id INT );
INSERT INTO liefe ( name ) VALUES ( 'HUGOCMS' );
INSERT INTO liefe ( name, person_id ) VALUES ( 'Inter-Data', 1 );
--SELECT * FROM liefe;

SELECT * FROM personen JOIN kunden ON ( personen.id = kunden.id ) WHERE kunden.person_id = 2;
SELECT * FROM personen JOIN liefe ON ( personen.id = liefe.id ) WHERE liefe.person_id = 1;

Die letzten beiden Zeilen sollen so zusammen gefasst werden, dass sie mit der id 1 und 2 funktionieren und dann Personen- und Kundendaten oder Personen- und Lieferantendaten liefert.
Dank und Gruß
Ronny

Ich denke, die beiden Tabellen Kunden und Lieferanten sollten eine Tabelle sein und ein Merkmal (Spalte) enthalten, ob es Kunden / Lieferanten sind.

Das geht leider nicht. Ich habe keinen Zugriff auf das komplette Projekt.

Dann möchtest Du vielleicht eine Sicht auf die Vereinigungsmenge von Kunden und Lieferanten haben, falls nötig mit dem besagten Merkmal. Das wäre dann ein UNION

Ich denke du meinst es so:

SELECT * FROM ( SELECT * FROM kunden WHERE person_id = 1 UNION SELECT * FROM liefe WHERE person_id = 1) AS cv JOIN personen ON ( person.id = cv.id ) ;

Nun erhalte ich jedoch die Fehlermeldung:
missing FROM-clause entry for table “person”
LINE 23: …efe WHERE person_id = 1) AS cv JOIN personen ON ( person.id …

Jein. Du verwendest keinen Alias für ‘JOIN personen ON …’, die cv.id gibt es nicht.
Außerdem solltest Du gerade bei einem UNION niemals Select * verwenden, sondern jede Spalte explizit nennen, sie müssen in Anzahl, Typ und natürlich Bedeutung passen.
Die explizite Angabe der Spalten dürfte auch Dir helfen, im JOIN die richtigen Feldnamen anzugeben.

Den Union würde ich nicht innen filtern sondern alle Daten wiedergeben, per View. Der Filter kommt dann außen in einem beliebigen Statement. Außerdem würde ich im Union eine extra Spalte spendieren, die die Datenherkunft wiedergibt. Sonst verlierst Du diese Information.

Vielen Dank für die Tips. Ich habe es jetzt so:

DROP  TABLE IF EXISTS personen CASCADE;
CREATE TABLE personen( id SERIAL, name TEXT );
INSERT INTO personen ( name ) VALUES ( 'Ronny Zimmermann' );
INSERT INTO personen ( name ) VALUES ( 'Dirk Schwatzer' );

DROP  TABLE IF EXISTS kunden CASCADE;
CREATE TABLE kunden( id SERIAL, name TEXT, person_id INT );
INSERT INTO kunden ( name ) VALUES ( 'Glaserei Falkenberg' );
INSERT INTO kunden ( name, person_id ) VALUES ( 'Bautech', 2 );

DROP  TABLE IF EXISTS liefe CASCADE;
CREATE TABLE liefe( id serial, name text,  person_id INT );
INSERT INTO liefe ( name ) VALUES ( 'HUGOCMS' );
INSERT INTO liefe ( name, person_id ) VALUES ( 'Inter-Data', 1 );

CREATE VIEW cv AS SELECT id, name, person_id, 'C'  AS cv FROM kunden UNION SELECT id, name, person_id, 'V' AS cv FROM liefe ;
SELECT * FROM cv;
SELECT cv.cv, cv.name, cv.id, personen.name AS p_name, personen.id AS p_id FROM cv JOIN personen ON ( cv.person_id = personen.id ) WHERE personen.id = 2;

Ist es möglich den View in die Abfrage einzubauen?
Ich wollte kein Datenbankupgrade durchführen.

Dank und Gruß Ronny

Ok, aber kleiner Hinweis:

ist bei der Angabe des ALIAS ‘cv’ unnötig, weil die Feldnamen durch das erste Select Statement des UNION Teils implizit definiert sind. Alles andere (spätere Definition von Aliasen) ist egal und hat damit höchsten dokumentarischen Effekt.

Verstehe ich nicht, Du hast den View namens CV erzeugt und bereits in der folgende Abfrage eingebaut.

Du musst außerdem bei der Nutzung von UNION Abfragen darauf achten, welche/ wieviele Datensätze für eine ID zurück gegeben werden (können), u.U. mehr als Du denkst. Sie unterscheiden sich im Extremfall nur durch das künstlich erzeugte Merkmal wie z.B. ‘C’ AS cv
Das musst Du dann von außen in der Abfrage, die den allgemeinen View verwendet, bei Bedarf weiter einschränken.

Falls Du damit (und mit vorherigen Aussagen) sagen willst, dass Du in der Datenbank eines Fremdprodukt arbeitest, kann ich nur zur Vorsicht raten, um nicht zu sagen abraten. Du kannst damit Garantieansprüche verlieren oder schlimmeres- besonders als Anfänger.

Nein, keine Sorge. Es handelt sich lediglich um eine Erweiterung eines Opensourceprojektes.
Da gibt es keine Garantie…
Ich wollte mir einfach nur den Aufwand für ein Datenbankupgrade sparen.

Es ist ja schließlich nur eine Abfrage…

Dieses Thema wurde automatisch 60 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.