SQL [SQLite]&[Relationalalgebra] Wie funktioniert der Ungleich-Operatur (!=, <>)?

T

Tersus

Gast
[SQLite]&[Relationalalgebra] Wie "not in" in Relationalalgebra ausdrücken?

Guten Tag,

folgende zwei Tabellen:

Code:
A              RekA
|----+------+   +-----+-----|
| ID | Name |   | aID | bID |
|----+------+   +-----+-----|
| 1  | ...  |   | 1   | 3   |
| 2  | ...  |   | 1   | 4   |
| 3  | ...  |   | 1   | 5   |
| 4  | ...  |   | 2   | 4   |
| 5  | ...  |   | 3   | 5   |
|----+------|   |-----+-----|

Ich möchte nun alle A.Namen haben, deren A.ID = RekA.aID ist, aber nicht RekA.bID!

(1) Ich dachte mir folgenden SQL Befehl:

Code:
select distinct Name from A join RekA on
ID = aID and ID != bID;

Im Ergebnis sollten nur die Namen der IDs 1 und 2 landen. Jedoch ist die 3 auch dabei! Die 3 befindet sich jedoch in der Spalte bID, was mich wundert.

(2) Erneuter Anlauf:

Code:
select distinct Name from A join RekA on
ID = aID where ID not in (
select bID from RekA)


Wieso funktioniert erstes Beispiel nicht? Und was viel wichtiger ist: Wie drücke ich letzteres in Relationalalgebra aus?

Mein Versuch

πID, NameID <> bID (A ⨝ID, aID RekA))

würde ja eher auf (1) zutreffen, wobei ich mir nicht sicher bin, in wie weit die on-Klausel mit der where-Klausel zusammenhängt.

Wie soll ich not in in Relationalalgebra ausdrücken?
 
Zuletzt bearbeitet von einem Moderator: (Titel angepasst)
Zu 1:

Ganz logische Sache, du verknüpfst die Tabellen A und RekA über die ID mit aID und !bID.

Du gehst also in Tabelle A. Gehst dort Zeile für Zeile durch. Dann guckst du in RekA ob ID = aID irgendwo existiert, wenn ja prüfst du ob ID <> bID.

Für ID = 3 gehen wir mal durch:

Es existiert ein Eintrag mit aID = 3, perfekt. Dann prüfen wir ob der Eintrag von bID <> ID (von dieser gefundenen Zeile!). Das passt auch, da bID = 5 und somit <> 3.
Zeile wird mit ausgegeben.

Es wird nicht geprüft ob in der ganzen Tabelle bID irgendwann mal 3 ist. Das prüfst du nur mit deiner zweiten Abfrage.

bei der rel. Algebra bin ich raus.
 
es soll nichts rein was a.id == b.id ist ^^ der sinn ergibt sich mir nicht.
wie wärs wenn du einfach aus RekA alle filterst wo a.id == b.id sind und gut^^

oder du hast es einfach kacke formuliert.

oder ist es so gemeint, dass a.id = id gelten muss, aber gleichzeitig das b.id keine id in name sein darf?
 
Mr.Smith schrieb:
es soll nichts rein was a.id == b.id ist ^^ der sinn ergibt sich mir nicht.
Wo habe ich denn geschrieben? Bitte noch mal richtig lesen. ;)


Noch mal zur Relationalalgebra.

Ich habe mich jetzt die kurze Zeit intensiver damit beschäftigt, habe aber keinen Schimmer, wie ich das "not in" ausdrücken soll. Evtl. mit einem ∉, aber das gehört doch eigentlich nur in die Mengenlehre ...
 
Zuletzt bearbeitet von einem Moderator:
Ich habe jetzt kein SQLite zu Hand, in Postgresql würde es nach etwas umstellen Deines 2. Aufruf so gehen:

Code:
SELECT DISTINCT Name FROM A AS t1, RekA AS t2
WHERE t1.id = t2.aid
AND t1.id NOT IN (SELECT bid FROM RekA)
 
Daichi schrieb:
Ich habe jetzt kein SQLite zu Hand, in Postgresql würde es nach etwas umstellen Deines 2. Aufruf so gehen:

Code:
SELECT DISTINCT Name FROM A AS t1, RekA AS t2
WHERE t1.id = t2.aid
AND t1.id NOT IN (SELECT bid FROM RekA)

Da kann man noch was einsparen:
Code:
SELECT DISTINCT name FROM a
WHERE id NOT IN (SELECT bid FROM rekA)

Als Join:
Code:
SELECT DISTINCT name FROM a
LEFT OUTER JOIN reka
  ON id = bid
WHERE bid IS NULL
 
fhtagn schrieb:
Code:
SELECT DISTINCT name FROM a
WHERE id NOT IN (SELECT bid FROM rekA)

Damit würden aber alle Namen aus Tabelle A ausgegeben werden, für die kein Eintrag in rekA bid vorliegt und es würde gar nicht geprüft, ob es überhaupt einen Eintrag für den Namen in rekA aid gibt, also werden auch die ausgegeben für die es evtl. bisher gar keinen Eintrag in rekA gibt, wenn die Kombination nicht vorkommen kann ok, aber sonst kann das Fehler produzieren.
 
AW: [SQLite]&[Relationalalgebra] Wie "not in" in Relationalalgebra ausdrücken?

@Daichi

Sehr gut erkannt. Ich wollte es gestern auch schon schreiben, bin aber nicht dazu gekommen.

@crvn075

Vielen Dank für den Link! Sehr hilfreich, wenn auch nicht völlig zufrieden stellend.

Ich bin aber mittlerweile selbst auf eine Lösung gekommen, bei der ich mir jedoch nicht so sicher. Es scheint in diesem Bereich niemanden zu geben, der sich wirklich gut auskennt.

A ⋈ID, aIDaID(RekA) ⊳ ρbID1⁄aIDbID (RekA)))

Der Ausdruck müsste stimmen.


Weiterhin ist das hier ganz interessant:

http://blog.montmere.com/2010/12/08/the-anti-join-all-values-from-table1-where-not-in-table2/
 
AW: [SQLite]&[Relationalalgebra] Wie "not in" in Relationalalgebra ausdrücken?

Tersus schrieb:
Code:
select distinct Name from A join RekA on
ID = aID and ID != bID;

Im Ergebnis sollten nur die Namen der IDs 1 und 2 landen. Jedoch ist die 3 auch dabei! Die 3 befindet sich jedoch in der Spalte bID, was mich wundert.

Wieso funktioniert das erste Beispiel nicht? Weil du mit dem Join nur einschränkst was wie wann gejoined werden soll, nicht was zurück kommt. Du bekommst quasi die komplette Tabelel A zurück, wo die Bedingung zutrifft bekommst du a gejoined mit der Zeile aus B zurück. Da du aber nur as A selektierst (Name) ist das äquivalent zu SELECT name FROM A.

Du kriegst also quasi zurück

ID aID bID
| 1 | 1 | 3 |
| 1 | 1 | 4 |
| 1 | 1 | 5 |
| 2 | 2 | 4 |
| 3 | NULL | NULL |
| 4 | NULL | NULL |
| 5 | NULL | NULL

(und halt die passenden Namen dazu)


Funktionieren würde zB: select distinct Name from A join RekA on
ID = aID and ID != bID WHERE aid IS NOT NULL;, sprich du schaust im WHERE ob der JOIN geklappt hat. Oder eben SELECT name FROM A WHERE EXISTS (SELECT 1 FROM RekA WHERE RekA.aID = A.ID AND A.ID != RekA.bID). Da gibts natürlich noch weitere Möglichkeiten.
 
Zurück
Oben