Abfrage einer m:n - Verknüpfung

HaWe51

Benutzer
Beiträge
24
Hallo,
ich habe folgende Tabellen erstellt (siehe ER-Diagramm.pdf).
tblA hat den Inhalt:
1, Helmut, Wagner
2, Chris, Hofmann
3, Emil, Sorglos

tblB hat den Inhalt:
1, AG1
2, AG2

tblKombi hat den Inhalt:
1, 1
1, 2
2, 1

Mit folgender Abfrage ermittle ich wer in welcher AG engagiert ist:
Code:
SELECT bArbeitsgruppe, aNachname
        FROM tblKombi
            INNER JOIN tblA ON k_aIdRef = aId
            INNER JOIN tblB ON k_bIdRef = bId;

Als Ergebnis erhalte ich:
Code:
AG1    Wagner
AG2    Wagner
AG1    Hofmann

Wie kann ich nun folgendes hinkriegen:
  1. Das Ergebnis-Set der Abfrage soll so gruppiert werden, dass ich folgende Ausgabe bekomme:
    Code:
    AG1   Wagner
          Hofmann
    AG2   Wagner

  2. Wie kann ich Abfragen, wer in keiner der AGs tätig ist, d. h. das Ergebnis-Set dürfte nur Emil Sorglos enthalten.
Mit der mir bekannten Group By - Klausel und entsprechender Sortierung erhalte ich zu 1. nur:
Code:
AG1 Wagner
AG1 Hofmann
AG2 Wagner
Mit bestem Dank im Voraus
Helmut
 

Anhänge

  • ER-Diagramm.pdf
    27,5 KB · Aufrufe: 5
Werbung:
so vielleicht?

Code:
test=*# select * from a;
 id |  name   
----+---------
  1 | wagner
  2 | hofman
  3 | sorglos
(3 rows)

test=*# select * from b;
 id | name
----+------
  1 | ag1
  2 | ag2
(2 rows)

test=*# select * from kombi ;
 a_id | b_id
------+------
    1 |    1
    1 |    2
    2 |    1
(3 rows)

test=*# with x as (select b.name as bname, a.name, row_number() over (partition by b.name order by k.b_id) from kombi k inner join a on k.a_id = a.id inner join b on k.b_id=b.id) select case when row_number=1 then bname else '' end,name from x ;
 case |  name  
------+--------
 ag1  | wagner
      | hofman
 ag2  | wagner
(3 rows)

test=*#
 
Wow

test=*# with x as (select b.name as bname, a.name, row_number() over (partition by b.name order by k.b_id) from kombi k inner join a on k.a_id = a.id inner join b on k.b_id=b.id) select case when row_number=1 then bname else '' end,name from x ;
case | name
------+--------
ag1 | wagner
| hofman
ag2 | wagner
(3 rows)

das ist ja ein Hammer, ich ziehe den Hut. Geht das für einen SQL-Anfänger auch etwas einfacher und in SQLite :eek: ?
 
Für diese Art der Formatierung von Ergebnissen ist SQL nicht gemacht worden, daher sind die Abfrage dafür auch etwas komplizierter.
So was macht man in der Regel wesentlich besser in der Anwendung, die die Daten anzeigt.

Soweit ich weiß, unterstützt die aktuelle SQLite version "Window Functions" (row_number() over ...).
Die Abfrage von akretschmer sollte also auch mit SQLite funktionieren.
 
@akretschmer: Vielen Dank für den Tipp. Ja, 'sql gruppenbruch' ist wohl das richtige Thema. Habe jede Menge dazu gefunden. Die meisten Beiträge lösen es aber in Verbindung mit php. Mit dem Thema muss ich mich also noch ein bisschen befassen. Fange ja gerade mal an mich in SQL mit SQLite einzuarbeiten :).

@castorp: Vielen Dank für den Hinweis. Ich habe mich bisher mit Access beschäftigt und da hätte ich einfach einen entsprechenden Report generiert.
Da ich von Windows zu macOS gewechselt habe, steht mir Access nicht mehr zur Verfügung. Daher arbeite ich mich jetzt in SQL mit SQLite und SQLite Studio ein, weil das mit macOS gleich mitgeliefert wird. Damit sind Reports aber wohl nicht möglich. Kennst Du eine OpenSource-Anwendung die in Verbindung mit SQLite/SQLite Studio die Erzeugung von Reports erlaubt?

@alle: Habt ihr vielleicht eine Lösung zu meiner 2. Frage im Ursprungspost? Mir geht es um die Frage, wie kann ich all das finden, das eine SELECT-Anweisung eben nicht liefert also quasi eine "NOT SELECT".
 
MS-Access ist ja auch eher ein FrontEnd als eine "Datenbank Engine". Ein Report ist letztendlich genau das, was ich mit "sollte in der Anwendung gemacht werden" gemeint habe.

LibreOffice erlaubt das Erstellen von Reports, ansonsten kenne ich keine (einfache) OpenSource Anwendung die das unterstützen würde.
Ich weiß aber nicht, ob das mit SQLite arbeitet. Standardmäßig wird da (embedded) Firebird verwendet - ist aber zum "SQL Lernen" genauso gut geeignet wie SQLite.
 
Habt ihr vielleicht eine Lösung zu meiner 2. Frage im Ursprungspost? Mir geht es um die Frage, wie kann ich all das finden, das eine SELECT-Anweisung eben nicht liefert also quasi eine "NOT SELECT".
Das wird typischerweise mit einem NOT EXISTS gelöst:

Code:
select a.*
from tbla a
where not exists (select *
                  from tblkombi k
                  where k.k_aidref = a.aid);

Online Beispiel: NOT EXISTS, PostgreSQL - rextester
 
Da die Spalte k_adiref mit hoher Wahrscheinlichkeit keine NULL Werte enthalten wird, kann man alternativ auch ein NOT IN verwenden:
Code:
select a.*
from tbla a
where aid not in (select k_aidref
                  from tblkombi k);
 
@castorp: Nochmals vielen Dank für Deine Hilfe. Das mit LibreOffice bzw. OpenOffice werde ich mal testen. Firebird ist ja -wenn ich das richtig verstanden habe - wie MySQL und PostgreSQL eine Client/Server-Umgebung. Das ist mir im Moment zum lernen zu aufwendig.
Deine beiden Lösungen zu meinem Problemchen #2 funktionieren beide. Genau das was ich gesucht habe :D.
 
PostgreSQL eine Client/Server-Umgebung. Das ist mir im Moment zum lernen zu aufwendig.

Kann man sich ja lokal auf dem Rechne/Laptop installieren und nutzen. PostgreSQL ist, finde ich, zum SQL-lernen ideal. Und wenn man später für eine Anwendung was 'richtiges' braucht hat man es gleich und kann damit umgehen.
 
@akretschmer: Mmh, da ist natürlich schon was dran. Ich werde mir auf der PostgreSQL-Seite noch einmal anschauen, wie man eine lokale Installation auf einem Mac macht.
Bietet PostgreSQL denn auch eine GUI vergleichbar mit SQLite Studio? Alles über die Konsole zu machen geht zwar, ist aber doch sehr aufwendig.
 
@castorp: Nochmals vielen Dank für Deine Hilfe. Das mit LibreOffice bzw. OpenOffice werde ich mal testen. Firebird ist ja -wenn ich das richtig verstanden habe - wie MySQL und PostgreSQL eine Client/Server-Umgebung.
Firebird ist (kann) beides: einen Client/Server Modus und einen "embedded" Modus. Wenn Du in LibreOffice die interne Datenbank verwendest, dann ist das (zumindest in der aktuellen Version) eine embedded Firebird Datenbank (OpenOffice verwendet die HSQLDB als embedded Datenbank). LibreOffice kann aber auch auf "externe" Datenbanken zugreifen.

Ich persönlich finde Postgres zum lernen auch die bessere Alternative. Der Funktionsumfang von SQLite ist zwar recht groß, aber ich finde den "Umgang" mit Datentypen eher fragwürdig. Man kann z.B. den Wert 'Niemals' in eine Spalte reinschreiben, die als DATE definiert wurde. Oder 2019-02-31. Das Verhalten ignoriert vollständig die Anforderungen des SQL Standards.

GUI Clients gibt es recht viele für Postgres. DBeaver, Squirrel, DBvisualizer, ExecuteQuery, HeidiSQL oder SQL Workbench/J können alle mit Postgres verwendet.

Ich werde mir auf der PostgreSQL-Seite noch einmal anschauen, wie man eine lokale Installation auf einem Mac macht.
Postgres.app – the easiest way to get started with PostgreSQL on the Mac
 
@castorp @akretschmer: Habe jetzt mal die Postgres.app installiert. Hat auch so weit alles geklappt. Einen kleinen Schönheitsfehler habe ich allerdings. Ich habe die Übung-DB mydb in dem Verzeichnis
/Users/.../Datenbanken/PostgresSQL angelegt. Wenn ich mich nun über die Postgres.app per Doppelklick mit der DB verbinde, habe ich im Terminal den endlosen Prompt
/Users/.../Datenbanken/PostgresSQL/mydb=#
Kann man das irgendwie ändern sodass nur noch mydb=# als Prompt erscheint?

@castorp: Welchen der OpenSource GUI Clients kennst Du denn aus eigener Erfahrung und kannst Du empfehlen?
 
Werbung:
Zurück
Oben