Eigenschaften auslesen
Hallo zusammen,
ich fange gerade an mich in ein wenig Reporting einzuarbeiten und stehe jetzt vor folgender Aufgabe:
ich brauche einen Report der eine Fixe anzahl an Eigenschaften darstellt:
Ich brauche folgendes Ergebnis:
Meine Datenbestand sieht wie folgt aus:
kann man eine entsprechende SQL abfrage schreiben?
Meine Idee war folgendes:
allerdings ergibt das folgendes:
hat jemand eine Idee wie man das aufbauen könnte?
ich fange gerade an mich in ein wenig Reporting einzuarbeiten und stehe jetzt vor folgender Aufgabe:
ich brauche einen Report der eine Fixe anzahl an Eigenschaften darstellt:
Ich brauche folgendes Ergebnis:
+---------------+-----------------+-----------------+-----------------+
| Person. Nr. | Eigenschaft 1 | Eigenschaft 2 | Eigenschaft 3 |
+---------------+-----------------+-----------------+-----------------+
| 222 | X | X | |
+---------------+-----------------+-----------------+-----------------+
| 999 | | X | X |
+---------------+-----------------+-----------------+-----------------+
+----+----------+-------------+
| id | personr | eigenschaft |
+----+----------+-------------+
| 59 | 222 | 1 |
| 60 | 222 | 2 |
| 76 | 999 | 2 |
| 64 | 999 | 3 |
+----+----------+-------------+
Meine Idee war folgendes:
select (case when eigenschaft = 4 then "X" else " " end)as e1,
(case when eigenschaft = 5 then "X" else " " end) as e2
from eigenschaften
+---------------+-----------------+-----------------+-----------------+
| Person. Nr. | Eigenschaft 1 | Eigenschaft 2 | Eigenschaft 3 |
+---------------+-----------------+-----------------+-----------------+
| 222 | X | | |
+---------------+-----------------+-----------------+-----------------+
| 222 | | X | |
+---------------+-----------------+-----------------+-----------------+
| 999 | | X | |
+---------------+-----------------+-----------------+-----------------+
| 999 | | | X |
+---------------+-----------------+-----------------+-----------------+
hat jemand eine Idee wie man das aufbauen könnte?
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 315853
Url: https://administrator.de/forum/eigenschaften-auslesen-315853.html
Ausgedruckt am: 06.04.2025 um 21:04 Uhr
8 Kommentare
Neuester Kommentar
Moin,
das sollte funktionieren, wenn du die Tabellen mit Inner join verknüpfst:
Folgender Code ist ungetestet, müsstest beim "where" ggf. mal mit AND und OR spielen
NACHTRAG: der Code enthält noch Fehler, eine korrigierte Version (von Biber) findet sich am Fuße des Threads
Ansonsten ist das WWW beim Suchbegriff "SQL ROW to COLUMN" sehr ergiebig.
Gruß
em-pie
P.S.
obiger Code berücksichtig nicht, dass wenn eine PersonalNr. keine Eigenschaft hat, dass diese dennoch angezeigt wird. Hier sollte dir statt Inner join ein Left Join Helfen
das sollte funktionieren, wenn du die Tabellen mit Inner join verknüpfst:
Folgender Code ist ungetestet, müsstest beim "where" ggf. mal mit AND und OR spielen
select
tbl_a.personr as PersoID
, tbl_a.eigenschaft as E1
, tbl_b.eigenschaft as E2
, tbl_c.eigenschaft as E3
from
TABELLE as tbl_a
inner Join TABELLE as tbl_b on
tbl_a.peronr = tbl_b.personr
inner Join TABELLE as tbl_c on
tbl_a.peronr = tbl_c.personr
where
tbl_a.eigenschaft='1'
and tbl_b.eigenschaft='2'
and tbl_c.eigenschaft='3'
Ansonsten ist das WWW beim Suchbegriff "SQL ROW to COLUMN" sehr ergiebig.
Gruß
em-pie
P.S.
obiger Code berücksichtig nicht, dass wenn eine PersonalNr. keine Eigenschaft hat, dass diese dennoch angezeigt wird. Hier sollte dir statt Inner join ein Left Join Helfen
Hallo schneerunzel,
mein Vorschlag:
Gruß
Friemler
mein Vorschlag:
SELECT personr
, (CASE WHEN SUM(CASE WHEN eigenschaft = 1 THEN 1 ELSE 0 END) > 0 THEN "X" ELSE " " END) AS e1
, (CASE WHEN SUM(CASE WHEN eigenschaft = 2 THEN 1 ELSE 0 END) > 0 THEN "X" ELSE " " END) AS e2
, (CASE WHEN SUM(CASE WHEN eigenschaft = 3 THEN 1 ELSE 0 END) > 0 THEN "X" ELSE " " END) AS e3
FROM eigenschaften
GROUP BY personr
ORDER BY personr
Gruß
Friemler
Moin schneerunzel,
ich würde auch Friemlers Strategie verwenden, allerdings wegen der Übersichtlichkeit so schreiben:
Ist von der Mimik nichts anderes, nur (für mich jedenfalls) lesbarer.
Grüße
Biber
ich würde auch Friemlers Strategie verwenden, allerdings wegen der Übersichtlichkeit so schreiben:
Select personr, max(e1) as e1, ,max(e2) as e2, max(e3) as e3 From (
SELECT personr
, (CASE WHEN eigenschaft = 1 THEN 'X' ELSE " " END) AS e1
, (CASE WHEN eigenschaft = 2 THEN 'X' ELSE " " END) AS e2
, (CASE WHEN eigenschaft = 3 THEN 'X' ELSE " " END) AS e3
FROM eigenschaften
) as whatever
GROUP BY personr
ORDER BY personr
Ist von der Mimik nichts anderes, nur (für mich jedenfalls) lesbarer.
Grüße
Biber
Mein Vorschlag hatte zudem noch einen Bug -.-
und statt Xe sähest du dort dann 1, 2 oder 3 und müsstest du mit CASE-Clauses "umbenennen".
Da die Querys von Friemler und Biber übersichtlicher und somit vermutl. auch performanter sind, wäre dies in der Tat der bevorzugte Weg (welchen du ja auch schon gewählt hast
und statt Xe sähest du dort dann 1, 2 oder 3 und müsstest du mit CASE-Clauses "umbenennen".
Da die Querys von Friemler und Biber übersichtlicher und somit vermutl. auch performanter sind, wäre dies in der Tat der bevorzugte Weg (welchen du ja auch schon gewählt hast
Moin em-pie,
das möchte ich nicht so stehen lassen.
Deine Idee, das Ganze über LEFT JOINs lösen zu wolle... na ja, machbar wäre es zwar.
Wenn es um eine Wette ginge oder so - Sinn macht es hier nicht.
Aber wenn es denn sein sollte, dann hat dein Ansatz oben ein paar Probleme:
Da kannst du mit einem LEFT JOIN dranflanschen was du willst... die personr 999 wird nie zur personr 222 passen.
Also brauchst du nicht einen Join über 3 Tabellen (für Eigenschaft 1, 2, 3), sondern musst diese 3 an eine 4te Tabelle knibbeln, in der alle personr einmalig stehen.
Dann wäre das Ergebnis
Bzw, etwas näher an den Vorgaben mit den Xen:
Ergebnis:
Aber das erscheint mir etwas überdimensioniert.
Grüße
Biber
das möchte ich nicht so stehen lassen.
Deine Idee, das Ganze über LEFT JOINs lösen zu wolle... na ja, machbar wäre es zwar.
Wenn es um eine Wette ginge oder so - Sinn macht es hier nicht.
Aber wenn es denn sein sollte, dann hat dein Ansatz oben ein paar Probleme:
- mit einem INNER JOIN würdes du ohnehin nur die Kombinationen bekommen, die alle drei Eigenschaften haben (also keinen Datensatz, da es das nicht gibt in den Spieldaten)
- aber auch mit einem LEFT JOIN ist doch die "führende Tabelle" bei dir die tbl_a.
Da kannst du mit einem LEFT JOIN dranflanschen was du willst... die personr 999 wird nie zur personr 222 passen.
Also brauchst du nicht einen Join über 3 Tabellen (für Eigenschaft 1, 2, 3), sondern musst diese 3 an eine 4te Tabelle knibbeln, in der alle personr einmalig stehen.
select
allpersonr.personr as PersoID
, tbl_a.eigenschaft as E1
, tbl_b.eigenschaft as E2
, tbl_c.eigenschaft as E3
from
(select distinct personr from eigenschaften) as allpersonr
Left Join
(select personr, eigenschaft from eigenschaften where eigenschaft =1) as tbl_a
on allpersonr.personr = tbl_a.personr
Left Join (select personr, eigenschaft from eigenschaften where eigenschaft =2 ) as tbl_b on
allpersonr.personr = tbl_b.personr
left Join (select personr, eigenschaft from eigenschaften where eigenschaft =3) as tbl_c on
allpersonr.personr = tbl_c.personr
PERSOID | E1 | E2 | E3
--------+----+----+---
222 | 1 | 2 |
999 | | 2 | 3
Bzw, etwas näher an den Vorgaben mit den Xen:
select
allpersonr.personr as PersoID
, tbl_a.E1
, tbl_b.E2
, tbl_c.E3
from
(select distinct personr from eigenschaften) as allpersonr
Left Join
(select personr, 'X' as E1 from eigenschaften where eigenschaft =1) as tbl_a
on allpersonr.personr = tbl_a.personr
Left Join (select personr, 'X' as E2 from eigenschaften where eigenschaft =2 ) as tbl_b on
allpersonr.personr = tbl_b.personr
left Join (select personr, 'X' as E3 from eigenschaften where eigenschaft =3) as tbl_c on
allpersonr.personr = tbl_c.personr
Ergebnis:
PERSOID | E1 | E2 | E3
--------+----+----+---
222 | X | X |
999 | | X | X
Aber das erscheint mir etwas überdimensioniert.
Grüße
Biber
Ich wusste, ich hatte etwas übersehen: Die Tabelle mit den gruppierten/ distincten Personalnummern.
Danke für's gerade ziehen! Hätte es vorher mal schnell testen sollen...
Werde oben mal noch, der Vollständigkeithalber einen Verweis auf deinen Post machen!
Nun gäbe es zwei Versionen, eine komplizierte (meine) und eine (bzw. zwei) schlanke, überschaubare Lösungen (Biber und Friemler).
Danke für's gerade ziehen! Hätte es vorher mal schnell testen sollen...
Werde oben mal noch, der Vollständigkeithalber einen Verweis auf deinen Post machen!
Nun gäbe es zwei Versionen, eine komplizierte (meine) und eine (bzw. zwei) schlanke, überschaubare Lösungen (Biber und Friemler).
Moin em-pie,
es gäbe eine weitere Strategie über "Inline-SELECTs", also quasi einen Sub-Select aus einer anderen Tabelle für übereinstimmende Werte mit der führenden Tabelle direkt in der Feldliste:
Resultset ist dann wie vorgegeben und oben abgebildet.
Dieses Vorgehen würde dann Sinn machen, wenn
In dem obigen Datenmodell ist das ja alles Asche - wenn da nicht diese künstliche "ID" als Schlüssel vorhanden wäre, sondern der primary key einfach auf "personr, eigenschaft" läge, dann wäre es sicher die allerschnellste Variante - alle Zugriffe auf die Daten liefen ausschliesslich über Indexfelder und überhaupt nicht auf den Datentabellen. Und ein teures GROUP BY zum Eindampfen des Resultsets ist nicht erforderlich.
Okay, hier bei den 4 Zeilen Beispieldaten ist es egal - von daher nur als ergänzender Kommentar gedacht.
P.S. @schneerunzel
Nein, ich merke gerade, ist mir nicht egal.
Der Aufbau der "Eigenschaften"-Tabelle ist Mist.
Du hast eine ID als Schlüsselattribut, nach dem nie nicht irgendjemand suchen wird und das wahrscheinlich auch in keiner Auswertung/in keinem Bildschirmformular jemals auftaucht.
Zusätzlich hast du das Problem, dass es eigentlich zwei alternative Schlüssel gibt, nämlich die "ID" und die Kombination aus "personr, eigenschaft".
In deinem Datenmodell ist auch nur sichergestellt, dass die ID eindeutig ist - zusätzlich musst du noch per Erfassungslogik oder zusätzliche UNIQUE-Constraint sicherstellen, dass nicht 12 Datensätze mit "Personr=222 und eigenschaft=1" da reindümpeln. Würde ja gehen, die haben alle unterschiedliche IDs.
Ich würde da auf eine künstliche ID verzichten.
Grüße
Biber
es gäbe eine weitere Strategie über "Inline-SELECTs", also quasi einen Sub-Select aus einer anderen Tabelle für übereinstimmende Werte mit der führenden Tabelle direkt in der Feldliste:
select
a.personr as PersoID
, (SELECT 'X' From eigenschaften e1 where e1.personr=a.personr and eigenschaft =1) as E1
, (SELECT 'X' From eigenschaften e2 where e2.personr=a.personr and eigenschaft =2) as E2
, (SELECT 'X' From eigenschaften e3 where e3.personr=a.personr and eigenschaft =3) as E3
from
(select distinct personr from eigenschaften) as a
Dieses Vorgehen würde dann Sinn machen, wenn
- die führende Tabelle, letzte Zeile im Statement (noch) kleiner werden könnte, z.B wenn ich nur auf bestimmte Personen (z.B. aus Abteilung XY) mit einer WHERE-Bedingung einschränken will
- die Verknüpfung bzw. das WHERE der SubSelects sich auf Attribute bezieht, auf denen ohnehin ein Index liegt, weil das die Schlüsselattribute sind
In dem obigen Datenmodell ist das ja alles Asche - wenn da nicht diese künstliche "ID" als Schlüssel vorhanden wäre, sondern der primary key einfach auf "personr, eigenschaft" läge, dann wäre es sicher die allerschnellste Variante - alle Zugriffe auf die Daten liefen ausschliesslich über Indexfelder und überhaupt nicht auf den Datentabellen. Und ein teures GROUP BY zum Eindampfen des Resultsets ist nicht erforderlich.
Okay, hier bei den 4 Zeilen Beispieldaten ist es egal - von daher nur als ergänzender Kommentar gedacht.
P.S. @schneerunzel
Nein, ich merke gerade, ist mir nicht egal.
Der Aufbau der "Eigenschaften"-Tabelle ist Mist.
Du hast eine ID als Schlüsselattribut, nach dem nie nicht irgendjemand suchen wird und das wahrscheinlich auch in keiner Auswertung/in keinem Bildschirmformular jemals auftaucht.
Zusätzlich hast du das Problem, dass es eigentlich zwei alternative Schlüssel gibt, nämlich die "ID" und die Kombination aus "personr, eigenschaft".
In deinem Datenmodell ist auch nur sichergestellt, dass die ID eindeutig ist - zusätzlich musst du noch per Erfassungslogik oder zusätzliche UNIQUE-Constraint sicherstellen, dass nicht 12 Datensätze mit "Personr=222 und eigenschaft=1" da reindümpeln. Würde ja gehen, die haben alle unterschiedliche IDs.
Ich würde da auf eine künstliche ID verzichten.
Grüße
Biber