SELECT-Problem mit mehreren Untertabellen

tower

Neuer Benutzer
Beiträge
2
Hallo Forum,

ich habe eine Tabelle "Person" und mehrere Tabellen "Antrag_x", "Antrag_y", ..., die jeweils per Fremdschlüssel auf "Person" zeigen.
Jede Antragstabelle kann 0 bis beliebig viele Einträge zu jeder Person enthalten.
Außerdem enthält jede Antragstabelle ein Feld "Status".

Ich möchte jetzt eine Selektion aller Personen, die in mindestens einer Antragstabelle mindestens einen Eintrag mit dem Status "neu" haben.
Jede Person soll nur einmal gelistet werden, auch wenn mehrere Anträge existieren, auf die obiges zutrifft.

Klingt eigentlich trivial, aber ich habe mir schon die Finger abgebrochen bei meinen Kombinationen aus DISTINCTs, JOINs usw... ich bekomme es nicht hin. 😔

Hat jemand eine Idee?
 
Werbung:
Klingt eigentlich trivial,
ja, vor allem klingt es nach dem missglückten Versuch einer Partitionierung.

Code:
postgres=# create table person(id int primary key, name text);
CREATE TABLE
postgres=# create table antrag(person int references person, status text, jahr int) partition by list(jahr);
CREATE TABLE
postgres=# create table antrag_20 partition of antrag for values in (20);
CREATE TABLE
postgres=# create table antrag_21 partition of antrag for values in (21);
CREATE TABLE
postgres=# create table antrag_22 partition of antrag for values in (22);
CREATE TABLE
postgres=# select distinct (person) from antrag where status = 'neu';
 person 
--------
(0 rows)

postgres=#

Du könntest jetzt für die nächsten 20.000 Jahre je eine Partition erstellen, an der Abfrage würde sich nichts ändern, sie würde weiter korrekt funktionieren.
 
Teile und herrsche lautet die Device.
Wenn Du auf einer Antragstabelle ein Select hinbekommt, dass dir die ID der Person mit Status neu ausgibt, schaffst Du es auch auf den anderen, sind ja alle gleich (leider).
Die Selects für alle Antragstabellen packst Du mit Union zusammen. Jetzt hast Du alle neuen Anträge mit einem Statement.
Das joinst Du mit den Personen.
Fertig.
 
Für mich klingt das so als würde er nicht nach Jahren partitionieren wollen sondern hätte unterschiedliche Antragsarten und für jede Antragsart 0 bis n Anträge zu jeder Person. Das Design ist natürlich nach wie vor nicht richtig. Besser wäre eine Entität Anträge, auch wenn sich der Inhalt der Anträge unterscheiden kann. Das kann man dann mit XML oder EAV oder sonst wie abbilden aber normalisiert wäre eine Entität Antrag, also eine Tabelle.

Ist das aus welchen Gründen auch immer nicht der Fall resultiert das schlicht in mehr Code und weniger Performance. Es gibt mehrere Wege die Information zusammen zu holen, z.b. so:
Code:
SELECT personen.*
FROM personen
LEFT JOIN antrag_x
ON ...
AND antrag_x.status = 'neu'
LEFT JOIN antrag_y
ON ...
AND antrag_y.status = 'neu'
WHERE antrag_x.id IS NOT NULL
OR antrag_y.id IS NOT NULL
 
Werbung:
Hallo zusammen,

danke erstmal für euren Input!
Zur Klärung: genau, hier wird nichts partitioniert, sondern die Anträge sind verschiedene Antragstypen. Diese haben auch völlig unterschiedliche Felder, weshalb ich sie auch in verschiedene Tabellen gepackt habe. Das ist aber tatsächlich noch ein Punkt, an dem ich auch hin und her gerissen bin.

Auf Grundlage eurer Ideen habe ich jetzt die Lösung gefunden - und weiß im Nachhinein ehrlich gesagt gar nicht mehr, wieso das nicht sofort funktioniert hat... manchmal hat man echt ein Brett vor dem Kopf...

So funktioniert es jetzt:

SQL:
SELECT DISTINCT (person.ID), person.name, ...
FROM person
LEFT JOIN antrag_x ON ...
LEFT JOIN antrag_y ON ...
LEFT JOIN ...
WHERE antrag_x.status = 1 or antrag_y.status=1 or ...

Danke für eure Hilfe!
 
Zurück
Oben