php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > SQL / Datenbanken
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


SQL / Datenbanken Probleme mit SQL? Hier könnt ihr eure Fragen zu SQL (MySQL, PostgreSQL, MS-SQL und andere ANSI-SQL Server) los werden.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 22-08-2009, 16:00
Boron
 Registrierter Benutzer
Links : Onlinestatus : Boron ist offline
Registriert seit: Aug 2004
Beiträge: 191
Boron ist zur Zeit noch ein unbeschriebenes Blatt
Standard XOR in Kombination mit IS NULL

Hallo,

XOR liefert doch TRUE, wenn eines der beiden Argumente TRUE ist, oder nicht?

Wenn ich also ein Anfrage mit "WHERE attr=10 XOR attr=11" formuliere, und attr ist 10 oder 11, dann wird die Zeile mit in das Ergebnis aufgenommen.


Wieso liefert XOR kein TRUE wenn ich mit IS NULL auf ein Attribut prüfe?

z.B. folgende Tabelle gegeben:
Code:
id  gegend_id  weg_id
1     9         NULL
Folgende Anfrage liefert kein Resultat:
Code:
SELECT * FROM `testxor`
WHERE 
(gegend_id=9 XOR gegend_id IS NULL) AND
(weg_id=7777 XOR weg_id    IS NULL)
Wenn ich aber das letzte XOR durch ein OR ersetze, dann wird die Zeile, die ich vorher auch schon erwartet hätte, zurückgegeben. Woran liegt das?
Mit Zitat antworten
  #2 (permalink)  
Alt 22-08-2009, 16:54
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Wenn zB. gegend_id NULL ist, ergibt es NULL = 9 XOR NULL IS NULL. NULL = 9 ergibt NULL, NULL IS NULL ergibt TRUE. Und jetzt kommts:

NULL XOR TRUE wird zu NULL
NULL OR TRUE wird zu TRUE

Ist bestimmt irgendwo im Handbuch dokumentiert, aber ich bin jetzt zu faul zum Suchen.

Logische Erklärung für mich wäre:

NULL ist weder TRUE noch FALSE, also kann es kein eindeutiges Ergebnis aus NULL XOR TRUE geben. Somit liefert MySQL einfach keinen Wert (NULL).
Wohingegen <WERT> OR TRUE immer TRUE ist, es gibt keine andere Möglichkeit.

Geändert von h3ll (22-08-2009 um 17:00 Uhr)
Mit Zitat antworten
  #3 (permalink)  
Alt 22-08-2009, 17:13
Boron
 Registrierter Benutzer
Links : Onlinestatus : Boron ist offline
Registriert seit: Aug 2004
Beiträge: 191
Boron ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Danke für die Erklärung, das leuchtet mir ein.

Zitat:
Zitat von h3ll Beitrag anzeigen
NULL XOR TRUE wird zu NULL
Gibt es eine Möglichkeit, das NULL zu TRUE umzubiegen?

Habe es eben mit einer IF-Konstruktion probiert, aber das wollte nicht so recht.
Mit Zitat antworten
  #4 (permalink)  
Alt 22-08-2009, 17:24
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

(gegend_id IS NOT NULL AND gegend_id = 9) XOR gegend_id IS NULL

Ich hoff aber, dass das nicht die tatsächliche abfrage ist, weil es so komplett unnötig aufgeblasen ist. Hier würde definitiv ein einfaches OR reichen.

Geändert von h3ll (22-08-2009 um 17:26 Uhr)
Mit Zitat antworten
  #5 (permalink)  
Alt 22-08-2009, 17:42
Boron
 Registrierter Benutzer
Links : Onlinestatus : Boron ist offline
Registriert seit: Aug 2004
Beiträge: 191
Boron ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Den Unterschied zwischen
(gegend_id IS NOT NULL AND gegend_id = 9) XOR gegend_id IS NULL
und
gegend_id = 9 XOR gegend_is IS NULL

verstehe ich gerade nicht.

Kannst du meine Frage bitte nochmal auf das SELECT aus dem Eingangspost beziehen?

Geändert von Boron (22-08-2009 um 17:49 Uhr) Grund: doppelt verwirrt
Mit Zitat antworten
  #6 (permalink)  
Alt 22-08-2009, 18:18
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Warum willst du hier überhaupt XOR verwenden? Ein OR tuts doch genauso.
Mit Zitat antworten
  #7 (permalink)  
Alt 22-08-2009, 18:47
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard

Zitat:
Zitat von Boron Beitrag anzeigen
Den Unterschied zwischen
(gegend_id IS NOT NULL AND gegend_id = 9) XOR gegend_id IS NULL
und
gegend_id = 9 XOR gegend_is IS NULL

verstehe ich gerade nicht.

Kannst du meine Frage bitte nochmal auf das SELECT aus dem Eingangspost beziehen?
Er hat NULL zu TRUE umgebogen, das wolltest du doch. Und in dem Beitrag wo du darum bittest, war der Bezug zum SELECT noch da.
Mit Zitat antworten
  #8 (permalink)  
Alt 22-08-2009, 19:36
Boron
 Registrierter Benutzer
Links : Onlinestatus : Boron ist offline
Registriert seit: Aug 2004
Beiträge: 191
Boron ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Zitat von h3ll Beitrag anzeigen
Warum willst du hier überhaupt XOR verwenden? Ein OR tuts doch genauso.
XOR und OR liefern unterschiedliche Ergebnisse.

Code:
CREATE TABLE `testxor` (
  `id` smallint(5) unsigned NOT NULL auto_increment,
  `gegend_id` int(11) unsigned default NULL,
  `weg_id` int(11) unsigned default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=12 ;

--
-- Daten für Tabelle `testxor`
--

INSERT INTO `testxor` (`id`, `gegend_id`, `weg_id`) VALUES
(1, 9, NULL),
(6, 10, 12),
(7, 10, 13),
(8, 9, 16),
(9, NULL, 17),
(10, 5, NULL),
(11, 10, NULL);
Ein
Code:
SELECT * FROM `testxor` WHERE (gegend_id=10 XOR gegend_id IS NULL)
gibt nur die Zeilen mit gegend_id = 10 zurück,

während ein
Code:
SELECT * FROM `testxor` WHERE (gegend_id=10 OR gegend_id IS NULL)
auch die mit NULL-befüllten Zeilen liefert.

Mein Problem ist jetzt: Wenn die angegebene gegend_id nicht existiert, sollen halt alle Zeilen mit NULL-Werten zurückgegeben werden. Doch
Code:
SELECT * FROM `testxor` WHERE (gegend_id=77 XOR gegend_id IS NULL)
tut das eben nicht. Obwohl NULL-Elemente für gegend_id existieren, bekomme ich ein leeres Resultat.
Mit Zitat antworten
  #9 (permalink)  
Alt 22-08-2009, 19:45
wahsaga
  Moderator
Links : Onlinestatus : wahsaga ist offline
Registriert seit: Sep 2001
Beiträge: 25.236
wahsaga befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Boron Beitrag anzeigen
Doch
Code:
SELECT * FROM `testxor` WHERE (gegend_id=77 XOR gegend_id IS NULL)
tut das eben nicht.
Wie soll es denn auch ...?

XOR verknüpft zwei Werte miteinander.
Hat deine Spalte gegend_id zwei Werte - in einem Datensatz? Natürlich nicht.

Völliger Humbug also, der komplette Ansatz.

Zitat:
Mein Problem ist jetzt: Wenn die angegebene gegend_id nicht existiert, sollen halt alle Zeilen mit NULL-Werten zurückgegeben werden.
Also willst du hier gar nicht die Inhaltes eines Datensatzes für sich genommen betrachten, sondern eine Betrachtung über mehrere Datensätze hinweg vornehmen.
Dafür sind JOINs das Mittel der Wahl - und kein Mangels Kenntnissen vollkommen blödsinnig angewandter logischer Operator XOR.
__________________
I don't believe in rebirth. Actually, I never did in my whole lives.
Mit Zitat antworten
  #10 (permalink)  
Alt 22-08-2009, 19:53
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard

Bevor wir jetzt anfangen uns im Kreis zu drehen, drück ich mal auf Reset:
Du willst alles selektieren wo gegend_id einen bestimmten Wert (z.B. 9) hat oder NULL ist. Richtig?
Du hast es mit "WHERE gegend_id = 9 XOR gegend_id IS NULL" versucht. Das soll zutreffen, wenn das eine oder das andere wahr ist (OR), es soll aber nicht zutreffen, wenn beides wahr ist (das X in XOR).
Nun ist es aber so, dass die beiden Fälle 9 und NULL verschieden voneinander sind. Wenn eins davon wahr ist, kann das andere nicht wahr sein. Das heißt, das X in XOR ist immer erfüllt und deshalb genügt ein einfaches OR.

Nun spreche ich hier ganz salopp von "wahr". Aber das Statement gegend_id = 9 wird, wenn gegend_id den Wert NULL hat, nicht TRUE oder FALSE sondern NULL. Dreiwertige Logik.
h3ll hat 17:24 Uhr gezeigt, wie du dieses gegend_id = 9 === NULL zu einem gegend_id = 9 === TRUE casten kannst. Sozusagen. Da findet natürlich kein Cast in dem Sinne statt. Er hat das Statement gegend_id = 9 einfach so erweitert, dass es nicht mehr ausgewertet wird, wenn gegend_id NULL ist. Damit hat er den fehlerverursachenden Fall ausgeklammert. Das ändert an der gewünschten Semantik des gesamten Statement nichts, da in diesem Fall ohnehin der rechte Teil vom XOR wahr wird und somit das XOR erfüllt.

So, das war nun wahrscheinlich nicht sehr erhellend. Ist aber auch egal. Ich drück nochmal Reset, wir besinnen uns auf dein Anliegen (selektieren wenn NULL oder 9) und formulieren
WHERE gegend_id = 9 OR gegend_id IS NULL
Mit Zitat antworten
  #11 (permalink)  
Alt 22-08-2009, 19:54
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Boron Beitrag anzeigen
Ein
Code:
SELECT * FROM `testxor` WHERE (gegend_id=10 XOR gegend_id IS NULL)
gibt nur die Zeilen mit gegend_id = 10 zurück,

während ein
Code:
SELECT * FROM `testxor` WHERE (gegend_id=10 OR gegend_id IS NULL)
auch die mit NULL-befüllten Zeilen liefert.
Und warum nicht einfach:

WHERE gegend_id = 10

Gibt nur die Zeilen mit gegend_id = 10 zurück. Ist doch, was du willst, oder?

Ansonsten, wenn du Zeilen willst, wo gegend_id den Wert 10 oder NULL hat, dann so, wie onenerd geschrieben hat:

WHERE gegend_id = 10 OR gegend_id IS NULL

Wozu willst du da jetzt noch ein XOR reinbringen? Es sind doch beide Fälle ohne XOR abgedeckt.

Geändert von h3ll (22-08-2009 um 19:56 Uhr)
Mit Zitat antworten
  #12 (permalink)  
Alt 22-08-2009, 19:59
Boron
 Registrierter Benutzer
Links : Onlinestatus : Boron ist offline
Registriert seit: Aug 2004
Beiträge: 191
Boron ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Zitat von onemorenerd Beitrag anzeigen
Du willst alles selektieren wo gegend_id einen bestimmten Wert (z.B. 9) hat oder NULL ist. Richtig?
Nein. Ich will alles selektieren, wo gegend_id = 9. Falls es KEIN Tupel dazu gibt, dann sollen mir alle Einträge, wo gegend_id NULL ist, zurückgegeben werden.
Mit Zitat antworten
  #13 (permalink)  
Alt 22-08-2009, 20:00
wahsaga
  Moderator
Links : Onlinestatus : wahsaga ist offline
Registriert seit: Sep 2001
Beiträge: 25.236
wahsaga befindet sich auf einem aufstrebenden Ast
Standard

Also ich hab das so verstanden:
Wenn nach gegend_id 4711 gesucht wird (durch Nutzereingabe), die in den Daten nicht vorhanden ist - dann will er stattdessen als Suchergebnis alle Datensätze bekommen, in denen gegend_id NULL ist.

(Der total abwegige Ansatz mag natürlich für das Verständnis des eigentlichen Anliegens erschwerend sein ...)
__________________
I don't believe in rebirth. Actually, I never did in my whole lives.
Mit Zitat antworten
  #14 (permalink)  
Alt 22-08-2009, 20:02
Boron
 Registrierter Benutzer
Links : Onlinestatus : Boron ist offline
Registriert seit: Aug 2004
Beiträge: 191
Boron ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Zitat von wahsaga Beitrag anzeigen
Also ich hab das so verstanden:
Wenn nach gegend_id 4711 gesucht wird (durch Nutzereingabe), die in den Daten nicht vorhanden ist - dann will er stattdessen als Suchergebnis alle Datensätze bekommen, in denen gegend_id NULL ist.
Genau
Mit Zitat antworten
  #15 (permalink)  
Alt 22-08-2009, 20:07
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Eventuell so:

Code:
SELECT *
FROM tabelle
WHERE IF(
    ( SELECT COUNT(*) FROM tabelle WHERE gegend_id = 9 ) > 0,
    gegend_id = 9,
    gegend_id IS NULL
)
Aber wirklich zufrieden bin ich damit nicht.
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
window.open in kombination mit php und div bereich lakul Archiv / Trash 6 17-03-2007 09:20
if - switch kombination??? joeCrack PHP Developer Forum 9 30-11-2005 11:23
Problem mit preg_replace in Kombination mit OOP hottemp PHP Developer Forum 2 02-07-2004 19:25
IS NOT NULL - oder doch NULL? Tekknotrip SQL / Datenbanken 5 20-04-2004 14:47
Kombination GROUP BY / SUM??? TobiaZ SQL / Datenbanken 11 04-01-2003 15:23

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 04:41 Uhr.