PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : "negativer" INNER JOIN ?!



inner.glow
14-02-2006, 15:57
Hallo!

Ich habe folgendes Problem:

Es handelt sich um eine MYSQL-Datenbank mit folgenden Tabellen (Meine eigentliche Datenbank ist sehr viel Komplexer, folgendes als Beispiel):

Tabelle: Kategorien
Felder: Name, ID

Tabelle: Artikel
Felder: Titel, ID, Inhalt, Kategorie

Wenn ich Alle Artikel haben möchte, die in einer Kategorie sind, verwende ich folgende Abfrage:


SELECT Artikel.*
FROM Artikel
INNER JOIN Kategorien (Kategorien.ID = Artikel.Kategorie)


Wenn nun ein neuer Artikel angelegt wird und keine Kategorie ausgewählt wird, ist der Wert für 'Kategorie' im jeweiligen Datensatz 0. Dadurch kann ich dann einfach abfragen, welche Artikel in keiner Kategorie sind:

SELECT * FROM Artikel WHERE Kategorie=0

Das Problem ist nur, dass es sein kann, dass eine Kategorie nachträglich gelöscht wird. Diejenigen Datensätze, die in der Kategorie enthalten waren werden nicht gelöscht und sind zukünftig keiner Kategorie zugeordnet!
Desshalb ist die 2. Abfrage nicht sinnvoll, da hier nur diejenigen Artikel ausgewählt wurden, die von Anfang an keiner Kategorie zugeordnet waren. Ich möchte aber ALLE Datensätze abfragen, die keiner Kategorie zugeordnet sind!

Wie funktioniert das?

sg, Fabian

PS: eigentlich geht es um eine sehr viel komplexere Abfrage, die um das oben beschriebene erweitert werden soll

Beispiel:



SELECT V.*
FROM veranstaltungen AS V
INNER JOIN termine AS T
ON (V.ID = T.veranstaltung)
WHERE T.ergt=0
AND V.p_kategorie=20
AND T.`erster_termin`>1141167600
AND T.`erster_termin`<1155679200
GROUP BY V.ID
ORDER BY T.`erster_termin`

mwanaheri
14-02-2006, 17:07
Wenn ich dein Beispiel richtig verstehe, gibt es zwei Möglichkeiten, mit denen ein Artikel keiner Kategorie zugeordnet sein kann:
1) Kategorie = 0, dabei ist 0 die Dummykategorie
2) kategorie = null, das scheint beim Löschen zu passieren.

1) erwischst du natürlich mit kategorie = 0, für 2) geht nur kategorie is null.
willst du also beide haben, sollte es mit
where kategorie = 0 or kategorie is null
gehen. Ich nehme an, auch unter mysql.

inner.glow
14-02-2006, 17:14
Nein. Wenn die Kategorie 2 gelöscht wird, bleibt im Artikel-Datensatz der Wert 2 für die Kategorie erhalten.

Ich möchte in meine Abfrage für jeden relevanten Datensatz in der Artikel-Tabelle prüfen, ob die angegebene Kategorie noch existiert.

sg.

mwanaheri
14-02-2006, 17:37
Oh, das hatte ich falsch verstanden. Also:
die Kategorie wird gelöscht, aber ihre ID bleibt in der Artikeltabelle vorhanden.
Die Artikel, die auf eine nicht vorhandene Kategorie verweisen solltest du mit

select artikel.id from artikel
where artikel.kategorie not in (select id from kategorie);

zu packen kriegen. Bei einer Fremdschlüsselbeziehung sollte es eigentlich nicht möglich sein, eine Kategorie zu löschen, auf die in der artikeltabelle verwiesen wird. So weit ich weiß kann mySQL das inzwischen auch. Wenn man dann löschen will, muss man das kaskadierend tun, so dass automatisch alle Einträge aus der Artikeltabelle gelöscht werden, die auf die zu löschende Kategorie verweisen.

elrond
16-02-2006, 15:17
ich glaube du suchst danach:


SELECT Artikel.*
FROM Artikel LEFT JOIN Kategorien on Kategorien.ID = Artikel.Kategorie
where karegorien.id is null


ich kanns leider grade nicht ausprobieren und beunutz es eher selten. sollte aber gehen

inner.glow
16-02-2006, 15:21
Hi!

Die Abfrage von mwanaheri war das, was ich gesucht hatte.

Andieser Stelle vielen Dank!

elrond
16-02-2006, 15:22
hossa, kann die mysql mittlerweile subselects ?!? :eek:

inner.glow
16-02-2006, 15:40
Ja, anscheinenend am MYSQL 4.1 - Bei 4.0 funktionierts noch nicht ------ Was mich wieder um einiges zurückwirft weil auf meinem Server Mysql 4.0 läuft NEEIIIN :mad:

Naja... ICh werd dann mal nach einer anderen Lösung suchen müssen... :-(

sg. Fabian

mwanaheri
16-02-2006, 19:01
Nun, ohne subselect könnte das klappen:

select * from artikel
left join kategorien on artikel.kategorie = kategorien.id
where kategorien.kategorie is null;

ok, eigentlich brauchst du nur die id vom Artikel, aber in diese Richtung würde ich gehen.

ups, sehe gerade, dass Elrond das schon vorgeschlagen hatte.

quinte17
17-02-2006, 10:16
hossa, kann die mysql mittlerweile subselects ?!? :eek:
also die 5.1 kann sie sogar schon richtig gut :D

folgende tabelle angenommen:


[reihe]
2
2
4
5
7
8
8

ziel ist es nun aus dieser spallte alle doppelten zahlen zu bekommen UND wenn lücken existieren, dann soll die nächstkleinere ausgegeben werden


select distinct a.reihe from nummern a
where exists (select 1 from nummern b where a.reihe = b.reihe group by b.reihe having count(1) > 1)
or not exists (select 1 from nummern c where c.reihe+1 = a.reihe)
order by a.reihe

greetz