Zwei Queries ... äquivalent?
Peter Thomassen
- datenbank
Hallo!
Ich habe hier zwei verschiedene Queries:
SELECT number, COUNT(contract.id\_contact-signatory
) as anz FROM contact
LEFT JOIN contract ON (contact.id = contract.id\_contact-signatory
)
GROUP BY number HAVING anz = 0
SELECT number FROM contact
WHERE id NOT IN(SELECT id\_contact-signatory
FROM contract)
Die erste funktioniert und liefert mir alle Kundennummern, für die kein Vertrag existiert. Die zweite wollte nach meinem Dafürhalten äquivalent zur ersten sein - und liefert mir ein leeres Resultset.
Lasse ich das NOT weg, so bekomme ich alle Kundennummern, für die ein Vertrag existiert - so grundsützlich fasch kann die Query also nicht sein. Woran liegt's?
Ich hab nicht viel Erfahrung mit Subqueries, also meldet euch bitte auch, wenn ihr der Meinung seid, dass es so eigentlich gehen müsste, damit ich wenigstens da auf der sicheren Seite bin. Danke!
Peter
Hallo
SELECT number FROM contact
WHERE NOT id IN(SELECTid\_contact-signatory
FROM contract)
sollte gehen.
Gruss,
Daniel
Hallo Peter Thomassen,
SELECT number, COUNT(contract.
id\_contact-signatory
) as anz FROMcontact
LEFT JOIN contract ON (contact.id = contract.id\_contact-signatory
)
GROUP BY number HAVING anz = 0
Meiner Meinung nach besser:
SELECT DISTINCT number
FROM contact
LEFT JOIN contract
ON contact.id = contract.id\_contact-signatory
WHERE contract.id\_contact-signatory
IS NULL
SELECT number FROM contact
WHERE id NOT IN(SELECTid\_contact-signatory
FROM contract)
nicht mit NOT IN, sondern <> ANY
SELECT number
FROM contact
WHERE id <> ANY (SELECT id\_contact-signatory
FROM contract)
http://dev.mysql.com/doc/mysql/en/ANY_IN_SOME_subqueries.html
NOT EXISTS dürfte auch eine Möglichkeit sein.
Die erste funktioniert und liefert mir alle Kundennummern, für die kein Vertrag existiert. Die zweite wollte nach meinem Dafürhalten äquivalent zur ersten sein - und liefert mir ein leeres Resultset.
Du kannst auf die COUNT-Funktion und die GROUP-BY-Klausel verzichten :-)
Ich hab nicht viel Erfahrung mit Subqueries, also meldet euch bitte auch, wenn ihr der Meinung seid, dass es so eigentlich gehen müsste, damit ich wenigstens da auf der sicheren Seite bin. Danke!
In sehr vielen Fällen sind Subqueries ineffizient. Dieses ist ein schönes Beispiel dafür.
Freundliche Grüsse,
Vinzenz
Hallo Vinzenz!
Meiner Meinung nach besser:
SELECT DISTINCT number
FROM contact
LEFT JOIN contract
ON contact.id = contract.id\_contact-signatory
WHERE contract.id\_contact-signatory
IS NULL
Danke.
SELECT number FROM contact
WHERE id NOT IN(SELECTid\_contact-signatory
FROM contract)nicht mit NOT IN, sondern <> ANY
SELECT number
FROM contact
WHERE id <> ANY (SELECTid\_contact-signatory
FROM contract)
http://dev.mysql.com/doc/mysql/en/ANY_IN_SOME_subqueries.html
Meint, dass id ungleich irgendeinem id_contact-signatory sein muss. Das ist wahr --> Selbes Ergebnis wie bei SELECT number FROM contact.
NOT EXISTS dürfte auch eine Möglichkeit sein.
Wie geht das dann?
In sehr vielen Fällen sind Subqueries ineffizient. Dieses ist ein schönes Beispiel dafür.
Warum?
Bye,
Peter
Hi,
In sehr vielen Fällen sind Subqueries ineffizient. Dieses ist ein schönes Beispiel dafür.
Warum?
EXPLAIN SELECT ...
Cheatah
Hallo,
In sehr vielen Fällen sind Subqueries ineffizient. Dieses ist ein schönes Beispiel dafür.
Warum?
EXPLAIN SELECT ...
Bitte verzeih mir, ich will hier keinen nerven oder rumtrollen ... aber mir sagt das echt nix. Beim Join sind die beiden Selects SIMPLE, beim Subselect der eine PRIMARY und der andere eine DEPENDENT SUBQUERY, Join verwendet als Extra "where", "temporary" und "distinct"; Subselect zweimal "where". Sonst gibt es keine Unterschiede.
Woraus kann ich jetzt schließen, dass der Subselect ineffizient ist?
Bye,
Peter
Hallo Vinzenz,
SELECT number FROM contact
WHERE id NOT IN(SELECTid\_contact-signatory
FROM contract)nicht mit NOT IN, sondern <> ANY
Klappt irgendwie nicht, kann den Fehler nicht finden ... mich nachgebauten, gleich strukturierten Tabellen funktioniert's. Naja, das bekomm ich schon noch irgndwie hin ...
Übrigens: "Use NOT (a = ANY (...)) rather than a <> ALL (...)." (http://dev.mysql.com/doc/mysql/en/Optimising_subqueries.html)
In sehr vielen Fällen sind Subqueries ineffizient. Dieses ist ein schönes Beispiel dafür.
"Replace a join with a subquery. For example, use this query:
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN (
SELECT column1 FROM t2);
Instead of this query:
SELECT DISTINCT t1.column1 FROM t1, t2
WHERE t1.column1 = t2.column1;"
Ebenfalls http://dev.mysql.com/doc/mysql/en/Optimising_subqueries.html.
Ich bin neugierig, was nun richtig ist.
Bye,
Peter
Hallo Peter Thomassen,
"Replace a join with a subquery. For example, use this query:
...
Ebenfalls http://dev.mysql.com/doc/mysql/en/Optimising_subqueries.html.
These tricks might cause programs to go faster or slower. Using MySQL facilities like the BENCHMARK() function, you can get an idea about what helps in your own situation.
Gleiche Quelle :-)
Freundliche Grüsse,
Vinzenz
Tach,
"Replace a join with a subquery. For example, use this query:
...
Ebenfalls http://dev.mysql.com/doc/mysql/en/Optimising_subqueries.html.
These tricks might cause programs to go faster or slower. Using MySQL facilities like the BENCHMARK() function, you can get an idea about what helps in your own situation.
Hm... warum steht das unter "Optimising Subquerise"? :-)
Grüße aus Würzburg,
Peter
Hi,
SELECT number, COUNT(contract.
id\_contact-signatory
) as anz FROMcontact
SELECT number FROM contact
Die erste funktioniert und liefert mir alle Kundennummern, für die kein Vertrag existiert. Die zweite wollte nach meinem Dafürhalten äquivalent zur ersten sein - und liefert mir ein leeres Resultset.
Nein, die beiden Queries sind keinesfalls Ergebnis-identisch. Die erste liefert zwei Spalten, die zweite nur eine.
cu,
Andreas
Hallo MudGuard,
SELECT number, COUNT(contract.
id\_contact-signatory
) as anz FROMcontact
SELECT number FROM contact
Die erste funktioniert und liefert mir alle Kundennummern, für die kein Vertrag existiert. Die zweite wollte nach meinem Dafürhalten äquivalent zur ersten sein - und liefert mir ein leeres Resultset.Nein, die beiden Queries sind keinesfalls Ergebnis-identisch. Die erste liefert zwei Spalten, die zweite nur eine.
Mh ja, das wusste ich :-) Ich meinte den Inhalt der ersten Spalte. Aber Du hast schon recht.
Bye,
Peter