Willkommen in der Webstatt
User-1 am 04.08.06 23:41

Frisch aus den Ferien zurück schon das nächste, kleinere Problem ;)

In einer Datenbank sind Hausschlüssel. Nun soll dieser Query alle Schlüssel raussuchen, dessen "owner" nicht in der Datenbank "accounts" existiert. Nun, ja. Zuerst hab ich ja das da gedacht..:

$sql = 'SELECT `items`.`id`,`items`.`value2` FROM `items`
INNER JOIN `accounts`
ON `accounts`.`acctid` = `items`.`owner`
WHERE `class` = "Schlüssel"
AND `value1` = "'.$session['user']['house'].'"
ORDER BY `id` ASC';


Aber nach dem ausprobieren musste ich merken, dass es das genaue Gegenteil bringt. Es listet die Schlüssel auf, die jemandem gehören. Nicht aber die, die niemandem gehören.
Weiss wer, wie ich es verdrehen kann?
Dass der Query einen Datensatz liefiert mit den Schlüsseln, dessen "owner" mit keinem Datensatz in der Tabelle "accounts" überreinstimmt?
(owner === acctid)

netcup.de Warum gibt es hier Werbung?
User-2 am 04.08.06 23:47

where not..?

User-1 am 04.08.06 23:53

Mh? Where not?
Wenn du dies nun als Baustein für den Query meinst:
Naja. Die Where-Klausel stimmt so ja. "class" muss "Schlüssel" sein, "value1" muss den Wert der Variabel haben. Das stimmt.
Das einzige ist diese Zeile hier:
ON `accounts`.`acctid` = `items`.`owner`

Einfach ein != hinmachen bringt ja nix. xyz-48n sieht es so aus:
http://www.legend-of-vinestra.de/schluessel3.jpg

Eventuell zur Veranschaulichung des ersten Querys:
http://www.legend-of-vinestra.de/schluessel1.jpg
Nur brauch ich die Nummern 8,9 und 12, dann das sind die, die "verloren" gegangen sind.

User-2 am 05.08.06 00:06

Ach so.. sry, hatte wohl zu sehr überflogen ;)

Aber wenn das item keinen owner hat, sollte das doch in der Datenbank gespeichert
sein, oder? Sprich, dass das owner Feld dann auf Null steht.

xyz-48n einfach
> select * from items where owner = null

User-1 am 05.08.06 00:11

Quote
Original von xyz-145
Ach so.. sry, hatte wohl zu sehr überflogen ;)

Aber wenn das item keinen owner hat, sollte das doch in der Datenbank gespeichert
sein, oder? Sprich, dass das owner Feld dann auf Null steht.

xyz-48n einfach
> select * from items where owner = null


Theoretisch, ja. Wenn der Account Ordnungsgemäss gelöscht wird, ist das auch so. Nur hat es wohl mehr irgendwo eine Löschmöglichkeiten, die das ausser Acht lassen. Somit irren in der Datenbank Schlüssel umher, die halt "verloren" sind.

Um das "Verloren"-sein nochmal zu erklären:
Ein Schlüssel ist dann verloren, wenn der Wert in der Spalte "owner" nicht in der Tabelle "accounts" zu finden ist.
Eine Mehr-Query-Möglichkeit hab ich ja. Zuerst alle schlüssel zum Haus holen und dann, Datensatz für Datensatz kontrollieren, ob owner in der Tabelle "accounts" ist.

Aber ich wollte es in einen Query bringen... Wenn mir jemand sagt, dass es unmöglich ist, ist auch gut ^^"

EDIT: Macht doch nichts... Wir überfliegen alle mal etwas zu schnell ;)

User-2 am 05.08.06 10:34

Ein bisschen gegoogelt, ein bisschen gelesen,
um dir sagen zu können, dass das mit outer join geht ;)

Ganz gut beschrieben wird die Technik hier unter "OUTER JOINs". :)

Deine Anfrage sollte dann in etwa so aussehen:
$sql = 'SELECT
i.`id`,i.`value2`
FROM
`items` as i
LEFT OUTER JOIN
`accounts` as a
WHERE
i.`class` = "Schlüssel"
AND i.`value1` = "'.$session['user']['house'].'"
AND a.`acctid` = i.`owner`
AND a.`acctid` IS NULL
ORDER BY i.`id` ASC';


Dabei werden beide Tabellen gejoint, ohne Rücksicht darauf zu nehmen, ob der passende
Datensatz in accounts existiert. Ist dem nicht so, werden einfach NULL Werte angehängt.

User-1 am 05.08.06 13:01

Ah... Intressant. xyz-48ke.
Aber ganz unverändert kann ich den Query leider nicht übernehmen - so endet es in einer Fehlermeldung:

Quote
#1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE i.`class` = "Schlüssel" AND i.`value1` = "1" AND a.`a


Ein wenig rumprobieren hat nun endlich das Ergebnis gebracht, das ich wollte:

SELECT
i.`id`,i.`value2`
FROM
`items` as i
LEFT OUTER JOIN
`accounts` as a
ON
a.`acctid` = i.`owner`
WHERE
i.`class` = "Schlüssel"
AND i.`value1` = "1"
AND a.acctid IS NULL
ORDER BY i.`id` ASC


Vielen xyz-48k für die fast richtige Lösung :)

Noch eine letzte Frage: Die Fehlermeldung... Liegt das an der MySQL-Version (MySQL 4.0.15)?

User-2 am 05.08.06 13:15

> Die Fehlermeldung... Liegt das an der MySQL-Version (MySQL 4.0.15)?

Ne.. ne.. ich hab die join Bedingung zu where statt zu on gesteckt -- darum ;)

Creative Commons Lizenzvertrag
Alle Inhalte des Webstatt-Archivs stehen unter einer Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 3.0 Unported Lizenz.

Impressum & Kontakt