[mysql5] Kartesisches Produkt eingrenzen
Christian
- datenbank
Hallihallo,
ich habe:
2 Tabellen:
A - id(primkey), name
B - nicht_unique_Spalte_mit_ids_aus_A (u.A.)
Ich will jetzt diejenigen A.id, A.name haben, wo A.id = B.id ist, also nur diejenigen Datensätze aus A, deren ID mindestens 1 mal in B als (nicht schlüssel-)attribut eingetragen ist.
SELECT A.id, A.name FROM A,B WHERE A.id = B.nicht_unique_Spalte_mit_ids_aus_A
liefert mir nun:
1 name1
1 name1
1 name1
2 name2
2 name2
ich wollte aber lediglich:
1 name1
2 name2
Klar, kommt durch die Bildung des Kartesischen Produkts, denn A.id taucht u.U. mehrmals in B.nicht_unique_Spalte_mit_ids_aus_A auf.
Tja. Und watt nu?
Kann man vllt. irgendwie einschränken, dass die Einträge dieser 'imaginären' Ergebnis-Tabelle unique sein müssen?
Schöne Grüße aus Münster
Christian
Hallo!
liefert mir nun:
1 name1
1 name1
1 name1
2 name2
2 name2ich wollte aber lediglich:
1 name1
2 name2Klar, kommt durch die Bildung des Kartesischen Produkts, denn A.id taucht u.U. mehrmals in B.nicht_unique_Spalte_mit_ids_aus_A auf.
Das sieht das ganz schwer nach einem GROUP BY aus.
SELECT A.id, A.name FROM A,B WHERE A.id = B.nicht_unique_Spalte_mit_ids_aus_A GROUP BY A.id, A.name
André Laugks
Moin!
Das sieht das ganz schwer nach einem GROUP BY aus.
Nein, nach einem SELECT DISTINCT.
- Sven Rautenberg
yo,
Das sieht das ganz schwer nach einem GROUP BY aus.
Nein, nach einem SELECT DISTINCT.
mal davon abgesehen, dass es sich hier nicht um das kartesische produkt handelt, da eine join anweisung vorhanden ist, ist in diesem falle die abfrage mit GROUP BY oder DISTINCT genau das gleiche.
Ilja
Hallo,
mal davon abgesehen, dass es sich hier nicht um das kartesische produkt handelt, da eine join anweisung vorhanden ist, ist in diesem falle die abfrage mit GROUP BY oder DISTINCT genau das gleiche.
Wobei mir die GROUP BY-Variante insofern besser gefällt, da sie die Absichten des Autors besser zur geltung bringt. Will heissen, dass DISTINCT eher nach zufälligen Ergebnissen 'riecht' während bei einer ausformulierten GROUP BY-Klausel es eher so scheint, dass sich schon jemand Gedanken darüber gemacht hat, was da an Ergebnissen kommen sollte (Wobei auch hier jemand ohne Hirn und Verstand zu Werke gegangen sein kann *g*).
Kurz: Ich mag DISTINCT in einem Produktionssystem nicht.
Grüße
Klaus
Hallo,
danke an alle (antworter) für die antworten!
Grüße
Christian
Hallo !
mal davon abgesehen, dass es sich hier nicht um das kartesische produkt handelt,
[...]
Dann waeren's naemlich 10 Ergenissaetze wenn ich dass richtig sehe
[...]
da eine join anweisung vorhanden ist,
ist in diesem falle die abfrage mit GROUP BY oder DISTINCT genau das gleiche.
[...]
Liegt das nicht eher daran, dass in dem SELECT nur Felder der unabhaengigen Tablle stehen ?
Wenn namlich auch noch 'name' oder irgendwas von der zweiten Tabelle B selektiert wuerde, wurde DISTINCT nicht mehr weiterhelfen.
Dann muesste man meines Erachtens sogar
GROUP BY A.id, A.name
verwenden.
Hingegen wuerde auch ein echtes Kreuzprodukt durch DISTINCT (wenn nur aus A ) oder GROUP BY eingeschraenkt, oder ?
[...]
Kurz: Ich mag DISTINCT in einem Produktionssystem nicht.
[...]
Wenn man's ganz genau nimmt koennte man zudem noch
ORDER BY NULL
Gruss
Holger
yo,
Dann waeren's naemlich 10 Ergenissaetze wenn ich dass richtig sehe
das kommt drauf an, wieviele daten sich in den beiden tabellen befinden. die anzahl der datensätze der beiden tabllen miteinander multipliziert ergibt die summe des ergebnisses eines kreuzproduktes (jeder mit jedem).
Liegt das nicht eher daran, dass in dem SELECT nur Felder der unabhaengigen Tablle stehen ?
nein, es liegt daran, dass die spaltenausgaben bei DISTINCT genau den spalten entspricht, über die du auch gruppieren würdest. und dabei ist es egal, aus welcher tabelle die spalten kommen.
GROUP BY ( und DISTINCT, was implizit GROUP BY verwendet ) sortiert naemlich hier implizit mit. Da ein String-Feld mit drin ist , koennte das evtl teuer werden- wie teuer haengt davon ab ob das Feld indiziert ist.
jede GROUP BY oder DISTINCT Anweisung sind letztlich nur sortierungen. insofern ist impliziet das falsche wort, weil es so gewollt ist.
Ilja
Hallo !
das kommt drauf an, wieviele daten sich in den beiden tabellen befinden.
Ach was !
die anzahl der datensätze der beiden tabllen miteinander multipliziert ergibt die summe des ergebnisses eines kreuzproduktes (jeder mit jedem).
Potzblitz !
Na dann 'lass uns mal sehen :
2 Datensaetze sind in A
A#1 wird auf 3 Saetze auf B abgebildet.
A#2 auf 2 Saetze aus B.
=> 5 Saetze in B, denn wen sollten die restlichen B-Datensaetze wohl referenzieren ?
( + ? mit NULL FK's aber in Anbetracht der Benennung der
FK - Feldes gehe ich davon aus, dass es NOT NULL ist )
=> 2*5 = 10 beim kartesischen Produkt.
Hatte ich nicht genau das geschrieben ?
Liegt das nicht eher daran, dass in dem SELECT nur Felder der unabhaengigen Tablle stehen ?
nein, es liegt daran, dass die spaltenausgaben bei DISTINCT genau den spalten entspricht, über die du auch gruppieren würdest.
Ja, namelich alle aus A, der unabhaengigen Tabelle der Relation. Was ich ja bereits geschrieben hatte.
und dabei ist es egal, aus welcher tabelle die spalten kommen.
Das stimmt nicht. Wenn aus B, wovon man ausgehen muss, verschiedene B-Werte for einen A-Datensatz mitselektiert wuerden, waeren die Rows ggf. DISTINCT auch wenn A.id und A.name doppelt auftraeten.
GROUP BY ( und DISTINCT, was implizit GROUP BY verwendet ) sortiert naemlich hier implizit mit. Da ein String-Feld mit drin ist , koennte das evtl teuer werden- wie teuer haengt davon ab ob das Feld indiziert ist.
jede GROUP BY oder DISTINCT Anweisung sind letztlich nur sortierungen.
Stimmt nicht. Zum Suchen brauch ich n, zum Sortieren n*log(n) Operationen. Auch in der Doku steht was zum diesbezueglichen
Overhead.
Gute Nacht !
Holger
yo,
=> 2*5 = 10 beim kartesischen Produkt.
Hatte ich nicht genau das geschrieben ?
nein, du bist davon ausgegangen, dass sich in der einen zwei und in der anderen fünf datensätze aufgrund einer JOIN anweisung befinden. ich würde diesen schluss nicht ziehen, da es sich um einen INNER JOIN und nicht um einen FULL OUTER JOIN handelt. es können sowohl in Tabelle A als auch in Tabelle B datensätze vorhanden sein, die der INNER JOIN nicht greift.
und dabei ist es egal, aus welcher tabelle die spalten kommen.
Das stimmt nicht. Wenn aus B, wovon man ausgehen muss, verschiedene B-Werte for einen A-Datensatz mitselektiert wuerden, waeren die Rows ggf. DISTINCT auch wenn A.id und A.name doppelt auftraeten.
hast du es schon mal ausprobiert, dass du mit einem DISTINCT und der ausgabe über die gleichen Spalten wie bei einem GROUP BY unterschiedliche ergebnisse rauskommen ? wie gesagt, es spielt keine rolle, aus welcher tabelle die spalten kommen. warum auch, weder DISTINCT noch GROUP BY sind so implementiert, dass es eine rolle spielen könnte.
jede GROUP BY oder DISTINCT Anweisung sind letztlich nur sortierungen.
Stimmt nicht. Zum Suchen brauch ich n, zum Sortieren n*log(n) Operationen. Auch in der Doku steht was zum diesbezueglichen
erstens reden wir nicht über suchen, sondern über sortieren. und zweitens zitiere ich einfach mal von der seite, die du angegeben hast:
"If you use GROUP BY, output rows are sorted according to the GROUP BY columns as if you had an ORDER BY for the same columns"
klingt doch sehr nach sortieren oder nicht ?
Ilja
Hallo !
[...]
es können sowohl in Tabelle A als auch in Tabelle B datensätze vorhanden sein, die der INNER JOIN nicht greift.
Da hast Du recht, nicht =, sondern >=10.
hast du es schon mal ausprobiert, dass du mit einem DISTINCT und der ausgabe über die gleichen Spalten wie bei einem GROUP BY unterschiedliche ergebnisse rauskommen ?
Ja, ich habe schon mal mit Datenbanken zu tun gehabt.
;-)
wie gesagt, es spielt keine rolle, aus welcher tabelle die spalten kommen. warum auch, weder DISTINCT noch GROUP BY sind so implementiert, dass es eine rolle spielen könnte.
Bei einem DISTINCT haettest Du aber gar nicht die syntaktischen Moeglichkeiten.
[...]
"If you use GROUP BY, output rows are sorted according to the GROUP BY columns as if you had an ORDER BY for the same columns"
Aber der Absatz geht noch etwas weiter (a.a.O.)
"To avoid the overhead of sorting that GROUP BY produces, add ORDER BY NULL:"
Das Problem an Deinem ersten Posting war aber gar nicht die Mengenlehre sondern eher die
Art das zu kommunizieren.
Gruss
Holger