sql: abfrage negieren?
-
hallo!
meine tabelle 'artikel' sieht etwa so aus:
artNr| .. -----|---- 123 456 789 111 222
folgendes statement gibt 2 datensätze zurück:
SELECT `artNr` FROM artikel WHERE `artNr` IN (123,111)
ich will allerdings genau alle anderen bekommen!
sowas wie:
SELECT `artNr` FROM artikel WHERE `artNr` [b]NOT[/b] IN (123,111)
.. funktioniert leider nicht, weil das NOT logisch interpretiert wird - am ende kommt nur müll raus.
ich kann leider kein:
SELECT `artNr`FROM artikel WHERE `artNr` != "123" AND `artNr` != "111"
benutzen, da es nicht schnell genug ist (in echt habe ich > 100000 abfragen). select braucht da ewigkeiten für!
frage nun also:
wie kann ich das ergebnis des SQL IN()s negieren?besten dank und schöne grüße:)
-
ok ich muss mich korrigieren.. ein IN() liefert nur 1, 0 oder null wieder. kann ich also vergessen - mein test hatte einen fehler, sorry.
mein problem besteht jedoch immernoch. ich brauche eine effiziente lösung für viele select-statements.
als beispiel mit nur 2645 ids in $ids:
$s_time = strtok(microtime(), " ") + strtok(" "); $id_array = split(',', $ids); for($n = 0; $n < sizeof($id_array); $n++) { $query = 'SELECT `artNr` FROM artikel WHERE `artNr` = '.$id_array[$n]; $res = mysql_query($query); if(mysql_num_rows($res) >= 1) $mysql_count++; } $e_time = strtok(microtime(), " ") + strtok(" "); echo "Dauer: ".number_format($e_time - $s_time, 6)." Sekunden<br>";
// Dauer: 327.262672 Sekunden
das sind über 5 minuten, dauert viel zu lange. habe max_execution_time etc schon hoch gesetzt, is ja aber auch keine lösung!
kann man das performanter machen?
beste grüße
-
Wieso machst Du das nicht so?
SELECT `artNr` FROM artikel WHERE `artNr` = $id[0] OR `artNr` = $id[1] OR ...
$sql='SELECT `artNr` FROM artikel WHERE'; for($i=0; $i<count($id_array); ++$i) { $sql.=' `artNr` = '.$id_array[$i]; if($i<count($id_array)-1) $sql.=' OR'; } $query=mysql_query($sql); while(false!==($result=mysql_fetch_array($query))) { // tue irgendwas, z.B. artNr ausgeben: print($result['artNr'].'<br />'); }
/EDIT: Wieso sollte artNR NOT IN (111, 222) nicht funktionieren? http://dev.mysql.com/doc/refman/5.1/de/comparison-operators.html sagt, dass es geht und hab es gerade mal selber ausprobiert, damit lassen sich toll die Dinger ausschließen.
-
Schon mal an einen JOIN gedacht?
Oder daran evtl. ein Feld in die Tabelle aufzunehmen, was sich da missbrauchen lässt für?
-
Hi perfo, welche Datenbank nutzt du? Ich verwende "NOT IN" regelmäßig unter PostgreSQL und dort funktioniert es wunderbar.
-
Zeigst Du uns bitte mal ein minimales Schema samt funktionierender SQL-Abfrage und EXPLAIN-Output? Danke.
-
entschuldigt bitte das späte antworten!
ich habe mich jetzt für eine lösung mit 'on duplicate key update' entschieden.. ich hatte ein paar logik-fehler in meinem alten ansatz. dieser weg hier erscheint mir nun weit aus besser und perfomanter:)vielen dank für eure mühe und schöne grüße!
-
problem ist ja gelöst und ich bin kein sql experte aber ich denke es hätte auch einfach mit einem verschachtelten select a la select where id != (select ...) oder so etwas in der richtung funktioniert.
-
Er.
Wenn "a NOT IN (...)" nicht geht, wieso dann nicht "NOT (a IN (...))"?
(Und "a NOT IN (...)" geht mit MS-SQL auch wunderbar, schreib ich immer so)