left join anwendung zur unterscheidung anhand tabelle mit spalte 1 oder 0

ich habe eine tabelle
-betrieb
mit den spalten
-betrieb.name
und
-betrieb.id,

dazu eine tabelle
-tätigkeit
mit den spalten
-tätigkeit.id_betrieb (verweist auf betrieb.id),
-tätigkeit.id_taetlist (verweist auf taetlist.id, siehe unten)
und
-tätigkeit.hauptneben (diese Spalte kann 0 oder 1 sein und kennzeichnet die tätigkeit mit neben =0 und haupt =1)

dazu gehört noch eine liste
-taetlist
mit den spalten
-taetlist.id,
-taetlist.name

mein Problem ist, das ich eine Abfrage brauche die die Spalten
-betriebsname (aus betrieb.name, kein problem)
und
-haupttaetigkeit
sowie
-nebentaetigkeit
enthält

wobei
-haupttaetigkeit
und
-nebentaetigkeit
aus
-taetlist.name gezogen werden sollen und anhand
-tätigkeit.hauptneben unterschieden werden sollen.

ich weiss dass ich da irgendwie mit left join ranmuss, komme damit aber gar nicht klar.

und würde mich sehr freuen über ein beispiel-SQL

Vielen Dank im Voraus!

select … from table1 left join table2 on (…) left join table3 on (…)

Einfach die JOIN-Bedingungen angeben.

Andreas

Ich glaub, ich war zu schnell. Dein Problem ist die Spalte in Abhöängigkeit des Wertes der einen Spalte (0 oder 1).

test=*# select * from betrieb ;
  name  | id
--------+----
 firma1 |  1
 firma2 |  2
(2 rows)

test=*# select * from taetlist ;
 id |    name
----+-------------
  1 | taetigkeit1
  2 | taetigkeit2
(2 rows)

test=*# select * from taetigkeit ;
 id_betrieb | id_taetlist | hauptneben
------------+-------------+------------
          1 |           1 |          0
          1 |           2 |          1
          2 |           1 |          1
          2 |           2 |          0
(4 rows)

test=*# select a.name, c.name, case when b.hauptneben = 1 then 'X' else '' end as haupt, case when b.hauptneben = 0 then 'X' else '' end as neben from taetigkeit b left join betrieba on (b.id_betrieb=a.id) left join taetlist c on (b.id_taetlist=c.id);
  name  |    name     | haupt | neben
--------+-------------+-------+-------
 firma1 | taetigkeit1 |       | X
 firma1 | taetigkeit2 | X     |
 firma2 | taetigkeit1 | X     |
 firma2 | taetigkeit2 |       | X
(4 rows)

Andreas

Danke das kommt meinem Wunsch schon sehr nahe allerdings soll es nur eine Ergebniszeile pro Firma geben, in der der nme der firma, und die namen der haupttätikeiten sowie bis zu drei nebentätigkeiten steht…

name haupttätigkeit nebentätigkeit1 nebentätigkeit2
--------±--------------±---------------±------
firma1 | name | name | name
firma2 | name | name | name

Was passiert bei mehr als 3 Nebentätigkeiten? Welche willst Du dann wegwerfen?

Anderer Ansatz:

Du listest das auf, damit redurziert sich das auf eine Aggregatfunktion. Die Doku enthält ein Beispiel für user-defined Aggregat-Funktionen, diese verwende ich nun:

test=*# select * from taetigkeit;
 id_betrieb | id_taetlist | hauptneben
------------+-------------+------------
          1 |           1 |          0
          1 |           2 |          1
          2 |           1 |          1
          2 |           2 |          0
          2 |           3 |          0
          2 |           4 |          0
(6 rows)

test=*# select a.name, array_to_string(array_accum(case when b.hauptneben = 1 then c.name else '' end),',') as haupt, array_to_string(array_accum(case when b.hauptneben = 0 then c.name else '' end),',') as neben from taetigkeit b left join betrieb a on (b.id_betrieb=a.id) left join taetlist c on (b.id_taetlist=c.id) group by a.name;
  name  |     haupt      |                neben
--------+----------------+--------------------------------------
 firma1 | ,taetigkeit2   | taetigkeit1,
 firma2 | taetigkeit1,,, | ,taetigkeit2,taetigkeit3,taetigkeit4
(2 rows)

Die Komma-Orgien könnte man noch mit regexp_replace eliminieren.

Andreas

HM, danke,
aber jetzt kriege ich nen ERROR: function array_accum(character varying) does not exist

scheint das es diese Funktion mit varchars in Postgresql nicht gibt?

Ja. Ist einer User-defined Aggregat-Funktion. Schrieb ich auch. Ich schrieb auch, daß diese in der Doku steht.

Hint:
die Online-Doku hat eine Suchfunktion. Erster Treffer. Bitte, Leute, lest die Doku.

Andreas

SORRY. jetzt gehts. Danke nochmals.

Nur habe ich bei haupt teilweise auch zwei Einträge. Ein Betrieb kann aber nur eine Haupttätigkeit haben. Woran kann das liegen? Dubletten?

Vermutlich. Passende Indexe können oft hilfreich sein…

Andreas

Okay. funktioniert jetzt alles.
Nur habe ich in Tabelle betrieb noch eine spalte land_id, die auf eine Tabelle der 16 Bundesländer verweist. Nun möchte ich im Ergebnis noch das zum Betrieb gehörige Bundesland anzeigen, bekomme das aber wieder nicht mit left join hin, sondern immer Fehlermeldung “ERROR: invalid reference to FROM-clause entry for table…”, egal wie ichs hindrehe…
Bitte nochmals um Hilfestellung…Danke!!

select … from betrieb b … left join bundeslaender bl on b.land_id=bl.id …

Ich denke mal, Du wirst das nun richtig hingedreht bekommen, oder?

Andreas

select … from betrieb b … left join bundeslaender bl on b.land_id=bl.id …
hatte ich natürlich schon durchgespielt…
… immer noch derselbe fehler. Ich brauche das innerhalb des Statements das du mir geschrieben hattest:

select a.name, array_to_string(array_accum(case when b.hauptneben = 1 then c.name else ‘’ end),’,’) as haupt, array_to_string(array_accum(case when b.hauptneben = 0 then c.name else ‘’ end),’,’) as neben , bundeslaender.name
from taetigkeit b
left join betrieb a on (b.id_betrieb=a.id)
left join taetlist c on (b.id_taetlist=c.id)
left join bundeslaender bl on a.land_id=bl.id
group by a.name;

und so wie ichs jetzt oben habe funzt das nicht…ich komm nicht drauf.

hm. keine antwort? ich hab echt ale variationne ausprobiert, es tut einfach nicht…

Wenn Du Alias-Namen verwendest:

end),',') as neben , bundeslaender.name
from taetigkeit b
left join betrieb a on (b.id_betrieb=a.id)
left join taetlist c on (b.id_taetlist=c.id)
left join bundeslaender bl on a.land_id=bl.id

dann tue dies konsequent überall.


Andreas

DANKE! das war genau das problem!.
Allerdingbekomme ich jetzte nur noch weniger als die Hälfte der Ergebniszeilen. Vorher warens knapp über 4000, jetzt ~1600.
Kann das mit den left joins zusammenhängen und sollte ich da lieber teilweise right joins verwenden?