Komplizierte SQL Query treibt mich in den Wahnisnn
Heinz
- datenbank
Hallo liebes Forum,
seit Stunden quält mich eine Query die einfach nicht das ausspuckt was sie soll. Vielleicht kann einer von euch weiterhelfen.
Etwas vereinfacht:
Tabelle "Dinger" (id, name, ding_art, sachen_count)
Tabelle "Sachen" (id, name)
Tabelle "Dinger_Sachen" (ding_id, sache_id)
Leicht zu erkennen: Ein Ding ist von einer ding_art und kann mehrere Sachen haben (Zwecks Optimierung wird die Anzahl der Sachen in sachen_count mitgespeichert).
Meine Anfrage: "Zu einer Menge von 'Sachen' gib mir alle 'Dinger' einer 'ding_art' die _mindestens_ _alle_ diese 'Sachen' haben"
Mein Ansatz bisher:
SELECT * FROM Dinger d
WHERE d.ding_art='tolles-ding'
AND d.sachen_count =
(SELECT COUNT(ds.sache_id) FROM Dinger_Sachen ds
WHERE ds.ding_id = d.id
AND ds.sache_id IN ("ids der geforderten Sachen")
GROUP BY ds.sache_id
HAVING COUNT(ds.sache_id) = d.sachen_count)
Naja, es spuckt einfach irgendwie nur die Dinger aus die nur eine Sache haben. Ich hab natürlich alle möglichen Variationen dieses Ansatzes probiert, wahrscheinlich ist er von Grund auf falsch...
Vieleicht weiß jemand von euch weiter... ?
Grüße Heinz
Hi
Hallo liebes Forum,
seit Stunden quält mich eine Query die einfach nicht das ausspuckt was sie soll. Vielleicht kann einer von euch weiterhelfen.
Keine Sorgen
Etwas vereinfacht:
Tabelle "Dinger" (id, name, ding_art, sachen_count)
Tabelle "Sachen" (id, name)
Tabelle "Dinger_Sachen" (ding_id, sache_id)Leicht zu erkennen: Ein Ding ist von einer ding_art und kann mehrere Sachen haben (Zwecks Optimierung wird die Anzahl der Sachen in sachen_count mitgespeichert).
Eigentlich brauchst du sachen_count gar nicht, denn mit den richtigen Datentypen und richtigen Abfragen geht es im SQL sauschnell, es sei denn deine Datensätze bewegen sich 5-stellig und aufwärts....
Meine Anfrage: "Zu einer Menge von 'Sachen' gib mir alle 'Dinger' einer 'ding_art' die _mindestens_ _alle_ diese 'Sachen' haben"
Mein Ansatz bisher:
SELECT * FROM Dinger d
WHERE d.ding_art='tolles-ding'
AND d.sachen_count =
(SELECT COUNT(ds.sache_id) FROM Dinger_Sachen ds
WHERE ds.ding_id = d.id
AND ds.sache_id IN ("ids der geforderten Sachen")
GROUP BY ds.sache_id
HAVING COUNT(ds.sache_id) = d.sachen_count)Naja, es spuckt einfach irgendwie nur die Dinger aus die nur eine Sache haben. Ich hab natürlich alle möglichen Variationen dieses Ansatzes probiert, wahrscheinlich ist er von Grund auf falsch...
Hab aufn Notebook leider keine Datenbank aber ich glaube du suchst nach JOIN. Es gibt 3 Typen: LEFT JOIN, INNER JOIN, RIGHT JOIN
LEFT JOIN:
select DING.ID_DING, DING.NAME, SACHEN.NAME
from DINGE
left join SACHEN on DINGE.ID_DING = SACHEN.ID_DING
spuckt alles aus, was einzig in DINGE ist und mehrfach in SACHEN sein kann. Es MUSS in Dinge vorkommen, aber KANN in SACHEN vorkommen.
INNER JOIN:
select DING.ID_DING, DING.NAME, SACHEN.NAME
from DINGE
inner join SACHEN on DINGE.ID_DING = SACHEN.ID_DING
spuckt alles aus, was in DINGE ist UND in SACHEN sein muss. Es MUSS in beiden Tabellen vorkommen, keine NULL-Werte.
RIGHT JOIN:
select DING.ID_DING, DING.NAME, SACHEN.NAME
from DINGE
inner join SACHEN on DINGE.ID_DING = SACHEN.ID_DING
spuckt alles aus, was in DINGE sein kann, aber in SACHEN sein muss. Wird am seltensten verwendet.
Stell es dir wie 2 Exceltabellen nebeneinander vor. Die linke Tabelle wird in der from-Kausel bestimmt (from DINGE).
Die rechte in der JOIN (join SACHEN).
LEFT JOIN: muss links vorkommen
INNER JOIN: muss in beiden vorkommen
RIGHT JOIN: muss rechts vorkommen
(OUTER JOIN): darf in beiden vorkommen (links-null + rechts-null erlaubt) <-- hab ich grad vergessen!
Vieleicht weiß jemand von euch weiter... ?
Grüße Heinz
Informier dich über die JOIN, damit kannst du alles regeln. Währenddessen schau ich mir deinen Code genauer an.
mfg Kadir
Hi
Tabelle "Dinger" (id, name, ding_art, sachen_count)
Tabelle "Sachen" (id, name)
Tabelle "Dinger_Sachen" (ding_id, sache_id)
Noch was, deine Datenbank scheint mir nicht normalisiert zu sein.
1.) Schau dir folgendes an:
http://de.wikipedia.org/wiki/Normalisierung_(Datenbank)
Es geht um Normalisierung der Tabellen
2.) Prüfe deine Datentypen für die Spalten
3.) Setze Primary Keys
Meld dich danach nochmal, da sich deine Datenbankstruktur evtl. ändern wird (nur noch 2 Tabellen?!). Dann wirds auch einfacher, weil ich hab das nicht so ganz kapiert. Oder kopier einige Datenbankdaten hier rein.
mfg Kadir
falls es sich um eine n:m beziehung handeln sollte, wäre das schon ok.
doch sollte er eine 1:n beziehung haben wollen, wäre die zwischentabelle unnötig.
auf jeden fall ist die spalte mit dem count unsinn.
was der fragesteller möchte, ist eine und-verknüpfung über mehrere zeilen.
da bei sql die und-bedingung immer nur innerhalb der zeile gilt, muß der fragesteller eine und-bedingung mit join auf die selbe tabelle zusammenbauen, damit die inhalte von 2 zeilen miteinander verglichen werden können.
yo,
die tabellennamen sind ein wenig eigenwillig, aber das ist ansichtssache. ich würde ihnen andere namen geben, falls es überhaupt was sinnvolleres gibt. aber das nur am rande.
Meine Anfrage: "Zu einer Menge von 'Sachen' gib mir alle 'Dinger' einer 'ding_art' die _mindestens_ _alle_ diese 'Sachen' haben"
ein vergleich mit der mitgeführten count spalte bring wenig, da es ja nur eine redudante information ist, wieviele einträge es von einem ding in der beziehungstabelle Dinger_Sachen.
die frage ist, was genau du mit "die _mindestens_ _alle_ diese 'Sachen' haben" meinst. das ist mir noch nicht ganz klar. was klar ist, ein ding hat mehrere sachen und dinger gehören zu ein ding_art, soweit ok. aber welche sachen sollen die dinger den nun haben ?
Ilja
Hi,
das hätte ich glatt für die Zitatesammlung vorgeschlagen:
was klar ist, ein ding hat mehrere sachen und dinger gehören zu ein ding_art, soweit ok. aber welche sachen sollen die dinger den nun haben ?
;-)
Viele Grüße
Jörg
Hallo,
Meine Anfrage: "Zu einer Menge von 'Sachen' gib mir alle 'Dinger' einer 'ding_art' die _mindestens_ _alle_ diese 'Sachen' haben"
Also ist es egal, ob das Ding mehr Sachen hat, so lange es nur alle gefragten sachen hat.
Das heis also, dass die Gesamtanzahl aller Sachen, die ein Ding hat, für diese Abfrage nicht von bedeutung ist.
Wie ermittelt man so etwas? Naja, ich würde meinen, am besten ermittelt man aus der Zuordnungstabelle alle Datensätze, die der gefragten Liste von Sachen entsprechen. Dann gruppiert man dieses Ergebnis nach den Dingen und vergleicht die Anzahl jeder Gruppe mit der Anzahl der Listeneinträge jener Sachen, die notwendig sind. Nur wenn diese beiden Zahlen gleich sind, dann erfüllt das Ding die Anforderung 'mindest alle angefragten Sachen'.
Danach könnten noch weitere Kriterien das Ergebnis einschränken, aber das sollte dann nicht mehr das Problem sein.
Grüße
Klaus