SQL-Abfrage umwandeln in SQL ohne Unterabfrage

09/07/2013 18:08 Shadow992#1
Heyho zusammen,

lässt sich diese Abfrage:

PHP Code:
SELECT 
FROM items
(
   
SELECT id 
   FROM items 
   WHERE 
   
(
      
value1=10 AND (value2=11 or value2=12)
   )
) as 
filtered
WHERE filtered
.id=items.id AND value1=15 
ohne Unterabfrage schreiben?

Meine Tabelle dazu sieht so aus:

Code:
id              value1               value2
0                 1                     10
0                 4                     10
0                 5                     15
0                 15                    20
0                 10                    11
1                 15                    18
1                 2                     20
1                 3                     11
1                 6                     12
Mit der Abfrage möchte ich alle Ids ehralten, die sowohl unter "value1=10 AND (value2=11 or value2=12)" existieren aber auch gleichzeitig unter "value1=15" existieren. Eine Id soll also nur ausgewählt werden, wenn beide Abfragen richtig sind.

Also würde man sie so verknüpfen:
PHP Code:
value1=10 AND (value2=11 or value2=12) AND value1=15 
Das liefert jedoch immer ein leeres Resultat zurück, da ich ja sage "Wähle diejenigen Datensätze aus, die sowohl value1=10 haben und value1=15".
Ich brauche aber viel mehr das:
"Wähle diejenigen Datensätze aus, die sowohl in der Datenbank mit dem Wert value1=10 existieren und mit dem Wert value1=15 und die gleichzeitig noch dieselbe ID haben".

In meinem Beispiel sollen also nur folgende Werte ausgewählt werden:
Code:
id              value1               value2
0                 15                    20
0                 10                    11
Kriegt man die obere Abfrage ohne Unterabfrage hin?
09/07/2013 18:41 Synatex#2
Das sind nun 2 unterschiedliche Querys. Einmal value1=10 und value1=15 die gleiche ID haben und die obrige, welche von beiden ists denn nun genau und vorallem, was spricht gegen einen Subquery?
09/07/2013 21:59 Shadow992#3
Quote:
Originally Posted by Synatex View Post
Das sind nun 2 unterschiedliche Querys. Einmal value1=10 und value1=15 die gleiche ID haben und die obrige, welche von beiden ists denn nun genau und vorallem, was spricht gegen einen Subquery?
Ich muss wenn ich diese Methode benutze bis zu 10 Subquerries machen und das zieht Performance wie sonst was. Jede Query die ich spare dürfte Zeit sparen. Ich würde auch gerne Zeiten vergleichen aber mir fällt nicht wirklich mehr ein als die obere Lösung.
09/07/2013 22:56 Else#4
Bei der Performance reden wir von "Millisekunden". Ansonsten ggf. weitere Ergebnisse vorher bereits auswerten? Bzw. eine größere Anzahl, zwischenspeichern, etc.
09/08/2013 12:01 Shadow992#5
Quote:
Originally Posted by Else View Post
Bei der Performance reden wir von "Millisekunden". Ansonsten ggf. weitere Ergebnisse vorher bereits auswerten? Bzw. eine größere Anzahl, zwischenspeichern, etc.
Jedes Request muss ich aber ca 10x ausführen und sind als Antwort eines Ajax-Requests gedacht. Plus Dns-LookUp, Html und Paar Php-Code braucht das Ganze trotzdem 2sec und da sind selbst 10msec pro Query in der Summe 100msec und das merkt man schon, daher bin ich für jegliche SQL bezogene Optimierungen dankbar. ;)
09/08/2013 23:15 flogi333#6
Ich habs noch nicht verstanden...

Also:
- value1 muss 10 oder 15 sein
- UND value2 muss 11 oder 12 sein

Bin ich da richtig?

BTW:
Quote:
Also würde man sie so verknüpfen:
PHP-Code:
value1=10 AND (value2=11 or value2=12) AND value1=15
Das kann nichts zurückgeben, da value1 nicht 10 UND 15 gleichzeitig sein kann
Sowie wenn du fragen würdest:
if( i == 0 && i == 1)
09/09/2013 00:22 _robox#7
propire es mal so der Query ist kürzer und übersichtlicher und macht genau das gleich
PHP Code:
SELECT t1.value1t1.value2t2.value1 AS value3t2.value2 AS value4 FROM items t1  LEFT JOIN items t2 ON t2.value1 15 WHERE t1.value1 10 AND t1.value2 IN(11,12); 
09/09/2013 00:48 Shadow992#8
Quote:
Originally Posted by _robox View Post
propire es mal so der Query ist kürzer und übersichtlicher und macht genau das gleich
PHP Code:
SELECT t1.value1t1.value2t2.value1 AS value3t2.value2 AS value4 FROM items t1  LEFT JOIN items t2 ON t2.value1 15 WHERE t1.value1 10 AND t1.value2 IN(11,12); 
Danke dir schonmal, ist aber leider langsamer. :/

Quote:
Originally Posted by flogi333 View Post
Ich habs noch nicht verstanden...

Also:
- value1 muss 10 oder 15 sein
- UND value2 muss 11 oder 12 sein

Bin ich da richtig?

BTW:
Das kann nichts zurückgeben, da value1 nicht 10 UND 15 gleichzeitig sein kann
Sowie wenn du fragen würdest:
if( i == 0 && i == 1)
Nein value1 muss 10 und 15 sein, wenn die item_id dieselbe ist.
Also bei ein und demselben item muss sowohl ein Eintrag value1=10 als auch ein Eintrag value1=15 existieren.
09/09/2013 01:10 _robox#9
Quote:
Originally Posted by Shadow992 View Post
Danke dir schonmal, ist aber leider langsamer. :/
das Ware mir aber neu das 'LEFT, JOIN' langsamer ist in gegen teil sie sind sogar aus per Formens grünten bestens geeignet um die anfragen zu buddeln.

ich wurde male dein php Code anschauen ob Mann ihn eventuell optimieren kann.
09/09/2013 12:59 Shadow992#10
Quote:
Originally Posted by _robox View Post
das Ware mir aber neu das 'LEFT, JOIN' langsamer ist in gegen teil sie sind sogar aus per Formens grünten bestens geeignet um die anfragen zu buddeln.

ich wurde male dein php Code anschauen ob Mann ihn eventuell optimieren kann.
Stimmt, war mein Fehler, ich hatte vergessen, dass mein Server immer SQL-Abfragen cached und meine SQL-Abfragen mit Subquerries waren bereits gecached, deswegen ging das extrem schnell. Jetzt wo der Cache ausgeschalten ist habe ich folgendes Ergebnis:

Quote:
10000 Abfragen mit Subquerries:
29sec

10000 Abfragen mit Left Join:
16sec
Danke dir, das ist genau der Geschwindigkeitsschub den ich brauchte. :)
Damit wäre die Frage für mich gelöst. Danke nochmals an alle Helfer.
09/14/2013 23:08 Synatex#11
Sorry dass das ganze etwas spät kommt, aber mit der oben genannten Formel hättest du 0 -15 - 20 gar nicht rausbekommen dürfen was du als Beispiel gegeben hast.

Weiß nicht wieviele Einträge das sind, dass ganze sollte aber auch (wenn ich die Beschreibung soweit richtig mitgekriegt hab) ohne extra Join gehen...

PHP Code:
SELECT FROM `itemsWHERE value1 IN(10,15) AND value2 IN(11,12